15

我正在尝试获取两个变量“week”和“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)

但是,我一定做错了什么,因为这个功能没有完成。有一个更好的方法吗?

输入:

id      week
1       1
1       2
1       3
1       1
2       3

输出:

  1  2  3
1 2  1  1
2 0  0  1
4

4 回答 4

20

您可以使用以下table命令:

table(data$id,data$week)

    1 2 3
  1 2 1 1
  2 0 0 1

如果“id”和“week”是数据框中唯一的列,您可以简单地使用:

table(data)
#    week
# id  1 2 3
#   1 2 1 1
#   2 0 0 1
于 2011-11-18T17:16:25.690 回答
14

你不需要ddply这个。dcastfromreshape2就足够了:

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

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

xtabs(~id+week, data=dat)

   week
id  1 2 3
  1 2 1 1
  2 0 0 1
于 2011-11-18T17:14:59.970 回答
11

需要这么长时间的原因ddply是按组拆分不是并行运行的(仅对“拆分”进行计算),因此对于大量组,它会很慢(并且.parallel = T)无济于事。

使用data.table::dcastdata.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

或显式设置参数:

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

对于data.table1.9.2 之前的替代方案,请参阅编辑。

于 2012-09-14T02:42:45.457 回答
1

一个tidyverse选项可能是:

library(dplyr)
library(tidyr)

df %>%
  count(id, week) %>%
  pivot_wider(names_from = week, values_from = n, values_fill = list(n = 0))
  #spread(week, n, fill = 0) #In older version of tidyr

#     id   `1`   `2`   `3`
#   <dbl> <dbl> <dbl> <dbl>
#1     1     2     1     1
#2     2     0     0     1

仅使用pivot_wider-

tidyr::pivot_wider(df, names_from = week, 
                   values_from = week, values_fn = length, values_fill = 0)

或使用tabylfrom janitor

janitor::tabyl(df, id, week)
# id 1 2 3
#  1 2 1 1
#  2 0 0 1

数据

df <- structure(list(id = c(1L, 1L, 1L, 1L, 2L), week = c(1L, 2L, 3L, 
1L, 3L)), class = "data.frame", row.names = c(NA, -5L))
于 2019-02-05T00:49:54.177 回答