一次聚集多次

时间:2015-10-04 14:15:41

标签: r reshape2 tidyr

说我有像这样的data.frame dat

id       X_a      X_b       Y_a      Y_b
v1 -0.012758 0.004537 -0.022725 0.005833
v2 -0.016706 0.003332 -0.006948 0.004965
v3 -0.005629 0.006972 -0.010578 0.006069

我希望它变得“聚集”。请注意,我们应收集X_aX_b以及Y_aY_b。期望的结果是:

id    X_Y_type         X         Y
v1       X_Y_a -0.012758 -0.022725
v2       X_Y_a -0.016706 -0.006948
v3       X_Y_a -0.005629 -0.010578
v1       X_Y_b  0.004537  0.005833
v2       X_Y_b  0.003332  0.004965
v3       X_Y_b  0.006972  0.006069
应用了两次

gather()不是我想要的:

dat %>%
  gather(X_type, X, X_a:X_b) %>%
  gather(Y_type, Y, Y_a:Y_b)

id X_type      X Y_type         Y
v1 X_a -0.012758    Y_a -0.022725
v2 X_a -0.016706    Y_a -0.006948
v3 X_a -0.005629    Y_a -0.010578
v1 X_b  0.004537    Y_a -0.022725
v2 X_b  0.003332    Y_a -0.006948
v3 X_b  0.006972    Y_a -0.010578
v1 X_a -0.012758    Y_b  0.005833
v2 X_a -0.016706    Y_b  0.004965
v3 X_a -0.005629    Y_b  0.006069
v1 X_b  0.004537    Y_b  0.005833
v2 X_b  0.003332    Y_b  0.004965
v3 X_b  0.006972    Y_b  0.006069

我希望将X_aY_aX_b匹配为Y_b,因此假的语法将是

dat %>%
  gather(X_type = Y_type, list(X, Y), list(X_a:X_b, Y_a:Y_b))

任何提示?

1 个答案:

答案 0 :(得分:3)

使用dplyr/tidyr,一个选项是gather/spread。我们将' wide'长期'格式使用key/value参数中的所有列,但' id'列,separate'键'栏目分为两部分,重塑“长”字样。广泛的#39;使用其中一个拆分列和' val',mutate' X_Y_type' paste列子串' X_Y _',并用{arrange>更改order

library(dplyr)
library(tidyr)
gather(dat, key, val, -id) %>% 
       separate(key, into=c('var1', 'X_Y_type')) %>%
       spread(var1, val) %>% 
       mutate(X_Y_type= paste0('X_Y_', X_Y_type)) %>%
       arrange(X_Y_type)
#  id X_Y_type         X         Y
#1 v1    X_Y_a -0.012758 -0.022725
#2 v2    X_Y_a -0.016706 -0.006948
#3 v3    X_Y_a -0.005629 -0.010578
#4 v1    X_Y_b  0.004537  0.005833
#5 v2    X_Y_b  0.003332  0.004965
#6 v3    X_Y_b  0.006972  0.006069

但是,可以使用melt中的data.table来完成此操作。 patterns参数中可能需要多个measure来转换广泛的'长期'格式。

library(data.table)#v1.9.6+
DT <- melt(setDT(dat), measure=patterns('^X', '^Y'), 
          value.name=c('X', 'Y'), variable.name='X_Y_type')

如果需要,&#39; X_Y_type&#39;可以使用paste将列值更改为预期输出。

DT[, X_Y_type := paste(names(DT)[2],
      unique(sub('.*_','', names(dat)[-1])), sep="_")[X_Y_type]]

DT
#   id   X_Y_type         X         Y
#1: v1 X_Y_type_a -0.012758 -0.022725
#2: v2 X_Y_type_a -0.016706 -0.006948
#3: v3 X_Y_type_a -0.005629 -0.010578
#4: v1 X_Y_type_b  0.004537  0.005833
#5: v2 X_Y_type_b  0.003332  0.004965
#6: v3 X_Y_type_b  0.006972  0.006069

或使用reshape

中的base R
reshape(dat, idvar='id', varying=2:ncol(dat), sep="_", direction='long')