首页 > 解决方案 > 如何在一行中转换不同的级别

问题描述

我有一组数据如下:

BETA_LACT   R   I   S
-   23  25  91
-   30  0   109
-   0   0   136
+   73  0   0
+   14  0   59
+   0   0   49

我想将数据转换为以下格式:

R_- I_- S_- R_+ I_+ S_+
23  25  91  73  0   0
30  0   109 14  0   59
0   0   136 0   0   49

我尝试了 spread() 但失败了,有人可以帮助我吗?

标签: rtidyversespread

解决方案


我怀疑您使用的问题spreadgather您的示例数据没有任何内容可以建议应该折叠哪些行。作为人类,我可以观察到您希望将第 1 行和第 4 行、第 2 行和第 5 行等组合在一起。但是,您的数据集中没有其他列或“键”可以表明这一点。

一种解决方案是添加一个索引列,如下面的第二个示例所示,使用group_byand mutate。以下reprex(可重现的示例)显示了与您的案例类似的非工作示例和工作示例。


library(tidyr)
library(dplyr)

example_data <- data.frame(
  categ = rep(1:3, 3),
  x = 1:9,
  y = 11:19,
  z = 21:29
)

# won't work
example_data %>%
  gather(var, value, -categ) %>%
  unite(new_col_name, var, categ) %>%
  spread(new_col_name, value)
#> Error: Duplicate identifiers for rows (1, 4, 7), (2, 5, 8), (3, 6, 9), (10, 13, 16), (11, 14, 17), (12, 15, 18), (19, 22, 25), (20, 23, 26), (21, 24, 27)

# will work
example_data %>%
  group_by(categ) %>%
  mutate(id = row_number()) %>% 
  gather(var, value, -categ, -id) %>%
  unite(new_col_name, var, categ) %>%
  spread(new_col_name, value)
#> # A tibble: 3 x 10
#>      id   x_1   x_2   x_3   y_1   y_2   y_3   z_1   z_2   z_3
#> * <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
#> 1     1     1     2     3    11    12    13    21    22    23
#> 2     2     4     5     6    14    15    16    24    25    26
#> 3     3     7     8     9    17    18    19    27    28    29

(作为旁注,请查看reprex包!这可以帮助您制作“可重复的示例”并提出更好的问题,这将有助于更好的社区支持。请注意复制上述代码并在本地运行它是多么容易。)


推荐阅读