首页 > 解决方案 > 将一列拆分为具有不同行数的多列

问题描述

我有一个包含两列的数据框:

dat_test <- data.frame(code     = c("A", "A", "A", "A", "B", "B", "B", "C", "C"),
                       response = c("A", "AA", "AB", "ABC", "BC", "AB", "B", "CDE", "BC"),
                       stringsAsFactors = FALSE)

dat_test

  code response  n
1    A        A 69
2    A       AA 85
3    A       AB 10
4    A      ABC 87
5    B       BC  3
6    B       AB 79
7    B        B 50
8    C      CDE 81
9    C       BC 32

我现在想以某种方式(理想情况下在 tidyverse 中)unstack/pivot_wider 这些数据,其中代码列被重新调整为三列,而行将只是来自响应列的值。这三个代码之间没有逻辑联系,即没有标识符可以告诉我代码“A”的哪个响应分别属于代码“B”和“C”的同一行。

所以基本上我只想要三列,将所有响应列为行,其他所有内容都填充为 NA。

我尝试了 tidyr 的 pivot_wider,但失败了。我看到在 pivot_wider 函数中有一些参数,比如 values_fill 和 values_fn,但我不知道是否可以使用这些参数来获得所需的行为。

预期结果将是:

# A tibble: 4 x 3
  A     B     C    
  <chr> <chr> <chr>
1 A     BC    CDE  
2 AA    AB    BC   
3 AB    B     NA   
4 ABC   NA    NA

有任何想法吗?

我想我可以首先创建一个额外的 id 列,该列从代码“A”的 1:4、代码“B”的 1:3 和代码“C”的 1:2 开始,但不确定如何动态地执行此操作任何其他数据集(即每个代码具有不同数量的代码和响应)。但是一旦我有了这样一个 id 列,旋转应该可以工作。

标签: rpivottidyr

解决方案


哦,我的,没关系(可以关闭)。

创建 id 很简单。这段代码就像一个魅力:

dat_test %>%
  group_by(code) %>%
  mutate(id = 1:n()) %>%
  ungroup() %>%
  pivot_wider(names_from = "code", values_from = "response")

并给出:

# A tibble: 4 x 4
     id A     B     C    
  <int> <chr> <chr> <chr>
1     1 A     BC    CDE  
2     2 AA    AB    BC   
3     3 AB    B     NA   
4     4 ABC   NA    NA 

推荐阅读