tidyr::收集多个不同类型的列

tidyr::收集多个不同类型的列,r,reshape,tidyr,R,Reshape,Tidyr,我正在尝试使用tidyr将宽格式转换为长格式,以收集具有不同类型的多个列。基本上与问题相同。我是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

我正在尝试使用tidyr将宽格式转换为长格式,以收集具有不同类型的多个列。基本上与问题相同。我是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=2
ID=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

获取您的输出,然后
mutate(ID=parse\u number(X\u num),col=str\u sub(X\u num,end=-3))%>%spread(col,
`)我认为这不会起作用,因为对于完整的数据集,并不是所有的变量都有3个字母的后缀。现在,如果我尝试,我会得到以下错误:
error:
var`必须计算为单个数字或列名,而不是函数。这一点很好。使用正则表达式可能有更好的方法,但Mauritz使用
tidyr::separate
的回答更简洁。如果您想删除分割变量的一部分,可以将其分配给
NA
:将
转换为=c(NA,“X_num”,“ss”)
将省去您以后删除
tmp
的需要,输出只是为了给出想法,但这很有效。我也接受了@divibisan的建议。非常感谢。
ID   X_num   abc   xyz
1     1       1     1    
1     2       2     2
1     3       2     1
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