首页 > 解决方案 > 在表上使用 pivot_wider 但保留行数

问题描述

所以我的问题如下,我有一个像这样的小数据框:

test_df <- data.frame(id=c(1,1,2,2,2), ttype=c("D", "C", "D", "D", "C"), val=c(1, 5, 10, 5, 100))
test_df
  id ttype val
1  1     A   1
2  1     B   5
3  2     A  10
4  2     A   5
5  2     B 100

现在我想让它更宽,最终变成这样:

     id        A        B     n
1     1        5        1     2
2     2      100       15     3

所以我想ttype用一个列替换每个值,按 id 和 的总和值分组val。但我的问题是我仍然想跟踪每个 id 总共出现了多少 A 或 B,n在这种情况下就是这样。

现在我找到了一种方法来做到这一点,但它非常难看。但这种方式有效:

test_df %>% 
  group_by(id, ttype) %>% 
  summarise(val = sum(val), n=n()) %>% 
  pivot_wider(names_from = ttype, values_from=c(val, n), values_fill=0) %>% 
  mutate(n=n_A+n_B) %>% 
  select(-n_A, -n_B)

结果是:

# A tibble: 2 x 4
# Groups:   id [2]
     id val_A val_B     n
  <dbl> <dbl> <dbl> <int>
1     1     5     1     2
2     2   100    15     3

所以这里 A 和 B 的数量分别包含在内,然后我将它们相加并删除其他两列。但这意味着我必须对列名进行硬编码,并且当 ttype 中的值超过 2 个时,它实际上并不可行。

我觉得必须有一个简单的方法来做到这一点,但我无法弄清楚。

标签: rdplyr

解决方案


您可以将id行数添加为新列,并pivot_wider通过取值来获取宽格式sum的数据val

library(dplyr)
library(tidyr)

test_df %>%
  add_count(id) %>%
  pivot_wider(names_from = ttype, values_from = val, values_fn = sum)

#     id     n     D     C
#  <dbl> <int> <dbl> <dbl>
#1     1     2     1     5
#2     2     3    15   100

推荐阅读