使用dplyr按用户折叠行

11

我希望根据用户折叠行,并将“1”放在它们对应的列中。

每个用户的每一行只能有一个“1”,因此不需要对随后的行进行任何添加。

我的数据框:

User  +1  +2  +3  +4  +5
   A   1   0   0   0   0
   A   0   1   0   0   0
   A   0   0   0   0   1
   B   0   0   1   0   0 
   B   0   0   0   1   0

预期结果:

User  +1  +2  +3  +4  +5
   A   1   1   0   0   1
   B   0   0   1   1   0 

非常感谢您的帮助。

3个回答

22

看起来你可以使用summarise_each

df %>% group_by(User) %>% summarise_all(funs(sum))

编辑说明:用现在已被弃用的summarise_each替换为summarise_all


1
简直不敢相信我之前不知道summarise_each这个函数。非常感谢! - ant
1
summarise_each在dplyr中已经被停用,也许可以将答案更改为summarise_all() - Gooze

7

以下是 dplyr 的另一种解决方案

df %>% group_by(User) %>% do(as.list(colSums(.)))

可能实现为data.table

library(data.table)
setDT(df)[, lapply(.SD, sum), User]

或者

setDT(df)[, as.list(colSums(.SD)), User]

或者使用基本的R语言,更加简单。
aggregate(. ~ User, df, sum)

3
我会先将数据转换为长格式,然后进行聚合,如果需要展示,再转回宽格式。使用tidyr工具实现如下:
df %>%
  pivot_longer(cols=-User, names_to="rating", values_to="count") %>%
  group_by(User, rating) %>%
  summarise(count = max(count)) %>% 
  spread(rating, count)

第一次聚合将其转换为长格式(使用p代替+):

> df <- read.table(header=TRUE, text='User  p1  p2  p3  p4  p5
   A   1   0   0   0   0
   A   0   1   0   0   0
   A   0   0   0   0   1
   B   0   0   1   0   0 
   B   0   0   0   1   0
')
> df %>% pivot_longer(
     cols=-User, names_to="rating", values_to="count")
# A tibble: 25 × 3
   User  rating count
   <chr> <chr>  <int>
 1 A     p1         1
 2 A     p2         0
 3 A     p3         0
 4 A     p4         0
 5 A     p5         0
 6 A     p1         0
 7 A     p2         1
 8 A     p3         0
 9 A     p4         0
10 A     p5         0
# … with 15 more rows

剩下的步骤是聚合,然后再转换为宽格式。

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