Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preserving zero length groups with aggregate

Tags:

r

aggregate

I just noticed that aggregate disappears empty groups from the result, how can I solve this? e.g.

`xx <- c("a", "b", "d", "a", "d", "a")
 xx <- factor(xx, levels = c("a", "b", "c", "d"))
 y <- rnorm(60, 5, 1)
 z <- matrix(y, 6, 10)
 aggregate(z, by = list(groups = xx), sum)`

xx is a factor variable with 4 levels, but the result gives just 3 rows, and would like a row for the "c" level with zeros. I would like the same behavior of table(xx) tha gives frecuencies even for levels with no observations.

like image 911
Carlos Avatar asked Feb 26 '26 01:02

Carlos


2 Answers

We can create another data.frame with just the levels of 'xx' and then merge with the aggregate. The output will have all the 'groups' while the row corresponding to the missing level for the other columns will be NA.

merge(data.frame(groups=levels(xx)),
   aggregate(z, by = list(groups = xx), sum), all.x=TRUE)

Another option might be to convert to 'long' format with melt and then use dcast with fun.aggregate as 'sum' and drop=FALSE

library(data.table)
dcast(melt(data.table(groups=xx, z), id.var='groups'), 
         groups~variable, value.var='value', sum, drop=FALSE)
like image 139
akrun Avatar answered Feb 27 '26 15:02

akrun


Since R 3.5.0, the new parameter "drop" was added, Hence, use following code

 aggregate(z, by = list(groups = xx), sum,drop=F)

The unused combination will be shown.

like image 40
lin Avatar answered Feb 27 '26 16:02

lin