更快速地计算频率和从长到宽的方式

use*_*419 8 aggregate r plyr reshape2

我试图获得两个变量的水平的每个组合的计数,"周"和"id".我希望结果将"id"作为行,将"week"作为列,将计数作为值.

到目前为止我尝试过的例子(尝试过其他一些东西,包括添加一个虚拟变量= 1然后再加fun.aggregate = sum上它):

library(plyr)
ddply(data, .(id), dcast, id ~ week, value_var = "id", 
        fun.aggregate = length, fill = 0, .parallel = TRUE)
Run Code Online (Sandbox Code Playgroud)

但是,我必须做错事,因为这个功能没有完成.有一个更好的方法吗?

输入:

id      week
1       1
1       2
1       3
1       1
2       3
Run Code Online (Sandbox Code Playgroud)

输出:

  1  2  3
1 2  1  1
2 0  0  1
Run Code Online (Sandbox Code Playgroud)

Jos*_*ich 19

你可以使用table命令:

table(data$id,data$week)

    1 2 3
  1 2 1 1
  2 0 0 1
Run Code Online (Sandbox Code Playgroud)

如果"id"和"week"是数据框中的唯一列,则可以使用:

table(data)
#    week
# id  1 2 3
#   1 2 1 1
#   2 0 0 1
Run Code Online (Sandbox Code Playgroud)

  • 如果您有大量数据和操作无法简化,那么'data.table'包可能会对您有所帮助. (3认同)

And*_*rie 13

你不需要ddply这个.在dcastreshape2足够:

dat <- data.frame(
    id = c(rep(1, 4), 2),
    week = c(1:3, 1, 3)
)

library(reshape2)
dcast(dat, id~week, fun.aggregate=length)

  id 1 2 3
1  1 2 1 1
2  2 0 0 1
Run Code Online (Sandbox Code Playgroud)

编辑:对于基本R解决方案(除了table- 由Joshua Uhlrich发布),请尝试xtabs:

xtabs(~id+week, data=dat)

   week
id  1 2 3
  1 2 1 1
  2 0 0 1
Run Code Online (Sandbox Code Playgroud)


mne*_*nel 10

原因ddply是需要花费很长时间才能按组进行拆分并不是并行运行(只有'拆分'上的计算),因此对于大量的组来说它会很慢(并且.parallel = T)无济于事.

使用data.table::dcast(data.table版本> = 1.9.2)的方法应该在时间和内存方面非常有效.在这种情况下,我们可以依赖默认参数值并简单地使用:

library(data.table) 
dcast(setDT(data), id ~ week)
# Using 'week' as value column. Use 'value.var' to override
# Aggregate function missing, defaulting to 'length'
#    id 1 2 3
# 1:  1 2 1 1
# 2:  2 0 0 1
Run Code Online (Sandbox Code Playgroud)

或明确设置参数:

dcast(setDT(data), id ~ week, value.var = "week", fun = length)
#    id 1 2 3
# 1:  1 2 1 1
# 2:  2 0 0 1
Run Code Online (Sandbox Code Playgroud)

有关data.table1.9.2之前的替代方案,请参阅编辑.