benhowell71
benhowell71

Reputation: 49

Calculating Stats from list of results in R

I'm trying to count results from one dataset that I imported into R and display those counts into a separate dataset that gets created within R for each unique Player.

Here is what a simplified version of the dataset looks like with only the relevant columns:

Label <- c("Raul", "Raul", "Raul", "Eric", "Eric", "Eric", "Aaron", "Aaron", "Aaron") 
Result <- c("s", "b", "fo", "s", "f", "b", "ss", "go", "s") 
df2 <- data.frame(Label, Result)

My data was compiled in Excel and exported as a CSV with about 4000 more rows of similar results and about 45 unique "Labels", but this smaller example shows you what the df looks like. Here is an example of what I want to end up with (line breaks to keep the rows separate):

Raul, count(s), count(b), count(fo), etc

Eric, count(s), count(b), count(fo), etc

Aaron, count(s), count(b), count(fo), etc

So that each unique "Label" for the players is on the row and the columns are the count of each type of Result. It should give me 45 rows, one for each of the unique players in my dataset.

I've been able to get the unique Player Labels just fine by running this:

dfstat <- data.frame(unique(df2$Label)

The problem comes when I try to get the counts for each type of result. I've tried a variety of things, like:

dfstat <- dfstat %>%
mutate(Strikes = count(subset(df2, Label = unique.df2.label & Result == "s")))

But I get this error code: Error: Column ``Strikes`` is of unsupported class data.frame

And

df34$Strikes <- count(subset(df2, Label = unique.df2.label & Result == "s"))

Gives me this error code: Error in ``$<-.data.frame``(``*tmp*``, Strikes, value = list(n = 9L)) : replacement has 1 row, data has 3

I'm doing something similar to be a part of a Shiny App and got that to work no problem, but that's because I was able to subset for my input value of a single Player. But I'm having trouble with getting this count data for ALL the unique players in my dataset into another dataset within R.

I appreciate any help with this issue because I'd really rather not manually type in all my different count formulas for every unique player. Thank you!

Upvotes: 0

Views: 149

Answers (3)

Ronak Shah
Ronak Shah

Reputation: 388907

You can use table to count the frequencies for each Player.

table(df2)

#       Result
#Label   b f fo go s ss
#  Aaron 0 0  0  1 1  1
#  Eric  1 1  0  0 1  0
#  Raul  1 0  1  0 1  0

If there are other columns in the data you can specify the columns whose frequency you want to count.

table(df2$Label, df2$Result)

A tidyverse approach would be :

library(dplyr)
library(tidyr)

df2 %>%
  count(Label, Result) %>%
  pivot_wider(names_from = Result, values_from = n, values_fill = 0)

Upvotes: 1

shea.fyffe
shea.fyffe

Reputation: 11

You could do a tapply followed by an rbind making sure that stats that are missing are given a count of 0.

res <- tapply(df2$Result, df2$Label, function(x) {
              x <- table(x)
              x[setdiff(unique(df2$Result), names(x))] <- 0
              return(x[order(names(x))])
             })

Then we can take this list of counts and rbind it

res <- do.call(rbind, res)

Your players will now be rownames

dfstat <- data.frame(label = row.names(res), res)

Upvotes: 0

akrun
akrun

Reputation: 887048

We could group by 'Label' and get the number of 's' elements by taking the sum of logical expression

library(dplyr)
df2 %>%  
      group_by(Label) %>%
      summarise(n = sum(Result == 's'))

Or to get the frequency of both column elements

count(df2, Label, Result)

If we need all the combinations, then do a complete before getting the count

library(tidyr)
df2 %>%
     mutate(n = 1) %>%
     complete(Label, Result, fill = list(n = 0)) %>%
     group_by(Label, Result) %>% 
     summarise(n = sum(n))

NOTE: count expects a data.frame/tibble as input, so it won't work within mutate where it receives a vector as input

Upvotes: 0

Related Questions