在表上使用 pivot_wider 但保留行数

时间:2021-01-06 11:23:47

标签: r dplyr

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

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 en B 的数量是单独包含的,之后我将它们相加并删除其他两列。但这意味着我必须对列名进行硬编码,并且当 ttype 中的值超过 2 个时,它就变得不可行了。

我觉得一定有一种简单的方法可以做到这一点,但我想不通。

1 个答案:

答案 0 :(得分:1)

您可以将 id 行的计数添加为新列,并使用 pivot_wider 通过取 sumval 值以宽格式获取数据。

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