一次聚集多次
gather multiple times at once
假设我有一个 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
我希望它变成 "gathered"。请注意,X_a
和 X_b
应与 Y_a
和 Y_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_a
到 Y_a
和 X_b
到 Y_b
的匹配,所以假语法是
dat %>%
gather(X_type = Y_type, list(X, Y), list(X_a:X_b, Y_a:Y_b))
有什么提示吗?
使用dplyr/tidyr
,一个选项是gather/spread
。我们使用 key/value
参数中除 'id' 列之外的所有列将 'wide' 转换为 'long' 格式, separate
'key' 列分为两个, 通过 paste
ing 子字符串 'X_Y_',使用拆分列之一和 'val'、mutate
'X_Y_type' 列从 'long' 重塑为 wide' ],并将 order
更改为 `arrange.
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
但是,这可以通过 data.table
中的 melt
来完成。它可以在 measure
参数中使用多个 patterns
来将 'wide' 转换为 'long' 格式。
library(data.table)#v1.9.6+
DT <- melt(setDT(dat), measure=patterns('^X', '^Y'),
value.name=c('X', 'Y'), variable.name='X_Y_type')
如果需要,可以使用 paste
.
将 'X_Y_type' 列值更改为预期输出
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
或使用 base R
中的 reshape
reshape(dat, idvar='id', varying=2:ncol(dat), sep="_", direction='long')
假设我有一个 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
我希望它变成 "gathered"。请注意,X_a
和 X_b
应与 Y_a
和 Y_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_a
到 Y_a
和 X_b
到 Y_b
的匹配,所以假语法是
dat %>%
gather(X_type = Y_type, list(X, Y), list(X_a:X_b, Y_a:Y_b))
有什么提示吗?
使用dplyr/tidyr
,一个选项是gather/spread
。我们使用 key/value
参数中除 'id' 列之外的所有列将 'wide' 转换为 'long' 格式, separate
'key' 列分为两个, 通过 paste
ing 子字符串 'X_Y_',使用拆分列之一和 'val'、mutate
'X_Y_type' 列从 'long' 重塑为 wide' ],并将 order
更改为 `arrange.
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
但是,这可以通过 data.table
中的 melt
来完成。它可以在 measure
参数中使用多个 patterns
来将 'wide' 转换为 'long' 格式。
library(data.table)#v1.9.6+
DT <- melt(setDT(dat), measure=patterns('^X', '^Y'),
value.name=c('X', 'Y'), variable.name='X_Y_type')
如果需要,可以使用 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
或使用 base R
reshape
reshape(dat, idvar='id', varying=2:ncol(dat), sep="_", direction='long')