Reputation: 49
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):
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
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
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
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