Reputation: 2570
tnt <- data.frame( g = rep(letters[1:2], each = 5), x = c(1:5,2:6), y = "things" )
library(plyr)
ddply(tnt, .(g,x), summarise, count = length(y) )
Considering the above code that is counting the number of rows for each x
value in each g
group:
What is the simplest way to have the level 6
represented in a
and 1
represented in b
? i.e. all levels of x
represented in all levels of g
.
My solution would be using as.data.frame(table(x))
after resetting the levels for each ddply
chunk to 1:6
but that seems cumbersome.
(I am not tied to using plyr if the simplest way involves base)
EDIT
The by @rrs answer is great (+1), however, it is my fault that in trying to create a easy example I over simplified the problem. There are many grouping factors (not just g
) and When I try .drop = FALSE
I get the following error:
Error: length(rows) == 1 is not TRUE
I think this might be because of many grouping factors that nevor occur together and never should. How can I do the following:
c4 <- data.frame( g = rep(letters[1:2], each = 5),
f = c(sample(letters[24:25], 5, replace = TRUE),
sample(letters[25:26], 5, replace = TRUE)),
x = c(1:5,2:6),
y = "things" )
ddply(c4, .(g,f,x), summarise, count = length(y), .drop = FALSE)
but the .drop = FALSE
should only apply to x
not g
and f
i.e. there should be no z
in a
.
Upvotes: 0
Views: 629
Reputation: 9893
Use .drop = FALSE
:
ddply(tnt, .(g,x), summarise, count = length(y), .drop = FALSE)
Upvotes: 2