【问题标题】:tidyr:: gather multiple columns different typestidyr:: 收集不同类型的多个列
【发布时间】:2019-04-09 23:32:01
【问题描述】:

我正在尝试使用 tidyr 将宽格式转换为长格式以收集具有不同类型的多个列。与here 提出的问题基本相同。我是 R 新手,不熟悉语法,所以可能会犯一些明显的错误。

我的数据如下所示:

ID    X_1_abc  X_1_xyz    X_2_abc    X_2_xyz   X_3_abc   X_3_xyz
1       1        1          2          2         2         1
2       1        2          1          0         1         NA 
3       1        2          1          1         NA        0

我试过以下代码:

df %<>% gather(var, val, X_1_abc:X_3_xyz) %>%   
  separate(var, c('var', 'X_number'), sep = 'X_*_', convert = TRUE) %>% 
  spread(var, val, convert = TRUE) 

但这只给了我两列:一列列出变量,另一列列出值。

ID  X_num `<NA>`
1   1_abc  1     
1   1_xyz  1     
1   2_abc  2     
1   2_xyz  2     
1   3_abc  2     
1   3_xyz  1 

我正在寻找以下内容:

ID   X_num   abc   xyz
1     1       1     1    
1     2       2     2
1     3       2     1

【问题讨论】:

  • 获取你的输出,然后mutate(ID = parse_number(X_num), col = str_sub(X_num, end = -3)) %&gt;% spread(col, `)
  • 我认为这行不通,因为对于完整的数据集,并非所有变量都有 3 个字母后缀。现在,如果我尝试,我会收到以下错误:Error: var` 必须计算为单个数字或列名,而不是函数`。
  • 好点。正则表达式可能有更好的方法,但 Mauritz 对tidyr::separate 的回答更简洁。

标签: r reshape tidyr


【解决方案1】:

我认为您的预期输出不完整,因为我没有看到 ID = 2ID = 3 的任何条目。

您可以执行以下操作

df %>%
    gather(k, v, -ID) %>%
    separate(k, into = c("tmp", "X_num", "ss"), sep = "_") %>%
    select(-tmp) %>%
    spread(ss, v)
#  ID X_num abc xyz
#1  1     1   1   1
#2  1     2   2   2
#3  1     3   2   1
#4  2     1   1   2
#5  2     2   1   0
#6  2     3   1  NA
#7  3     1   1   2
#8  3     2   1   1
#9  3     3  NA   0

【讨论】:

  • 如果你想删除分割变量的一部分,你可以将它分配给NA:做into = c(NA, "X_num", "ss")会省去你以后删除tmp的需要
  • 是的,输出只是为了给出这个想法,但这非常有效。我也接受了@divibisan 的建议。谢谢!
猜你喜欢
  • 2017-03-06
  • 1970-01-01
  • 2016-08-14
  • 2015-12-20
  • 2019-04-08
  • 2020-02-08
  • 1970-01-01
  • 1970-01-01
  • 2018-07-28
相关资源
最近更新 更多