将数据从长格式转换为宽格式,包括求和和计数。

6
我正在尝试在R中将数据从长格式重塑为宽格式。我想通过ID获取类型变量的出现次数和第二个变量(val)的值的总和,如下例所示。
我能够找到关于计数或求和重塑的答案,但没有同时满足两者的解决方法。
以下是原始数据示例:
> df <- data.frame(id = c(1, 1, 1, 2, 2, 2),
+                  type = c("A", "A", "B", "A", "B", "C"),
+                  val = c(0, 1, 2, 0, 0, 4))
> df
  id type val
1  1    A   0
2  1    A   1
3  1    B   2
4  2    A   0
5  2    B   0
6  2    C   4

我想要得到的输出如下所示:
  id A.count B.count C.count A.sum B.sum C.sum
1  1       2       1       0     1     2     0
2  2       1       1       1     0     0     4

在这里,count列显示类型A、B和C的出现次数,而sum列则显示按类型累加后的值。

为了实现计数,我可以像这个答案中建议的那样,使用reshape2::dcast函数,默认聚合函数为length

> require(reshape2)
> df.c <- dcast(df, id ~ type, value.var = "type", fun.aggregate = length)
> df.c
  id A B C
1  1 2 1 0
2  2 1 1 1

同样地,正如这个答案中建议的那样,我也可以使用dcast函数中的sum聚合函数作为输出来执行重塑操作:

> df.s <- dcast(df, id ~ type, value.var = "val", fun.aggregate = sum)
> df.s
  id A B C
1  1 1 2 0
2  2 0 0 4

我可以合并这两个:

> merge(x = df.c, y = df.s, by = "id", all = TRUE)
  id A.x B.x C.x A.y B.y C.y
1  1   2   1   0   1   2   0
2  2   1   1   1   0   0   4

但是否有一种方法可以一次性完成所有操作(不一定使用dcastreshape2)?

3个回答

5
自 data.table v1.9.6 起,可以对多个 value.var 列进行转换,并通过提供多个 fun.aggregate 函数进行转换。请见下文:
library(data.table)

df <- data.table(df)
dcast(df, id ~ type, fun = list(length, sum), value.var = c("val"))
   id val_length_A val_length_B val_length_C val_sum_A val_sum_B val_sum_C
1:  1            2            1            0         1         2         0
2:  2            1            1            1         0         0         4

2
这里介绍一种使用 tidyverse 的方法。
library(tidyverse)
df %>% 
  group_by(id, type) %>%
  summarise(count = n(), Sum = sum(val)) %>%
  gather(key, val, count:Sum) %>%
  unite(typen, type, key, sep=".") %>%
  spread(typen, val, fill = 0)

1
建议使用 data.table 解决方案可能更好,但如果您更喜欢使用 dcast,并且有许多 value.var/fun.aggregate 组合,您也可以这样做:
library(purrr)

cols <- c('type', 'val')
funs <- c(length, sum)

map2(cols, funs, ~ dcast(df, id~type, value.var = .x, fun.aggregate = .y)) %>% 
  reduce(left_join, by='id', suffix=c('.count', '.sum'))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接