我有一个带有一个(或多个)id变量的数据集和许多具有相同结构的变量子集。我想以长格式堆叠这些子集:我的示例中有三个子集,因此最终表必须有三倍的行,并且id变量必须是三重的。
foo_data
表是我在R中的数据示例:
individuals <-c("individual1","individual2","individual3")
subset1.var1 <- c("value1","value2","value3")
subset1.var2 <- c("value4","value5","value6")
subset1.var3 <- c("value7","value8","value9")
subset2.var1 <- c("value10","value11","value12")
subset2.var2 <- c("value13","value14","value15")
subset2.var3 <- c("value16","value17","value18")
subset3.var1 <- c("value19","value20","value21")
subset3.var2 <- c("value22","value23","value24")
subset3.var3 <- c("value25","value26","value27")
foo_data <-data.frame(individuals,subset1.var1,subset1.var2,subset1.var3,subset2.var1,
subset2.var2,subset2.var3,subset3.var1,subset3.var2,subset3.var3)
foo_data
这就是我想要的:
structure(list(id = structure(c(1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L,
3L), .Label = c("individual1", "individual2", "individual3"), class = "factor"),
var1 = structure(1:9, .Label = c("value1", "value2", "value3",
"value10", "value11", "value12", "value19", "value20", "value21"
), class = "factor"), var2 = structure(1:9, .Label = c("value4",
"value5", "value6", "value13", "value14", "value15", "value22",
"value23", "value24"), class = "factor"), var3 = structure(1:9, .Label = c("value7",
"value8", "value9", "value16", "value17", "value18", "value25",
"value26", "value27"), class = "factor")), .Names = c("id",
"var1", "var2", "var3"), row.names = c(NA, 9L), class = "data.frame")
# individuals time var1 var2 var3
# individual1.subset1 individual1 subset1 value1 value4 value7
# individual2.subset1 individual2 subset1 value2 value5 value8
# individual3.subset1 individual3 subset1 value3 value6 value9
# individual1.subset2 individual1 subset2 value10 value13 value16
# individual2.subset2 individual2 subset2 value11 value14 value17
# individual3.subset2 individual3 subset2 value12 value15 value18
# individual1.subset3 individual1 subset3 value19 value22 value25
# individual2.subset3 individual2 subset3 value20 value23 value26
# individual3.subset3 individual3 subset3 value21 value24 value27
最明显的解决方案是计算一个循环,如下所示:
stacked_foo <- foo_data[,c(1:4)]
noms <- c("id","var1","var2","var3")
names(stacked_foo) <- noms
for (i in 2:3){
c(1,(3*i-1):(3*(i+1)-2))
temp <- foo_data[,c(1,(3*i-1):(3*(i+1)-2))]
names(temp) <- noms
stacked_foo <- rbind(stacked_foo,temp)
print(i)
}
但是,有没有更快,更简洁的内容,内置函数如melt
或stack
?
答案 0 :(得分:4)
reshape
功能这是reshape
(来自基地R)的任务,但它希望您的data.frame
名称格式略有不同。
试试这个:
names(foo_data) <- gsub("(.*)\\.(.*)", "\\2.\\1", names(foo_data))
names(foo_data)
# [1] "individuals" "var1.subset1" "var2.subset1" "var3.subset1" "var1.subset2"
# [6] "var2.subset2" "var3.subset2" "var1.subset3" "var2.subset3" "var3.subset3"
如果你的名字是这种格式,你可以这样做:
reshape(foo_data, direction = "long", idvar = "individuals",
varying = 2:ncol(foo_data))
# individuals time var1 var2 var3
# individual1.subset1 individual1 subset1 value1 value4 value7
# individual2.subset1 individual2 subset1 value2 value5 value8
# individual3.subset1 individual3 subset1 value3 value6 value9
# individual1.subset2 individual1 subset2 value10 value13 value16
# individual2.subset2 individual2 subset2 value11 value14 value17
# individual3.subset2 individual3 subset2 value12 value15 value18
# individual1.subset3 individual1 subset3 value19 value22 value25
# individual2.subset3 individual2 subset3 value20 value23 value26
# individual3.subset3 individual3 subset3 value21 value24 value27
您可以使用rownames(your-new-df-name) <- NULL
删除时髦的rownames。
melt
和dcast
如果您想转到reshape2
路线,可以尝试(假设列名称未已更改):
library(reshape2)
dfL <- melt(foo_data, id.vars = "individuals") ## Warning ahead, but OK
# Warning message:
# attributes are not identical across measure variables; they will be dropped
X <- colsplit(dfL$variable, c("SUB", "VAR"), pattern = "\\.")
dcast(dfL, individuals + X$SUB ~ X$VAR, value.var = "value")
# individuals X$SUB var1 var2 var3
# 1 individual1 subset1 value1 value4 value7
# 2 individual1 subset2 value10 value13 value16
# 3 individual1 subset3 value19 value22 value25
# 4 individual2 subset1 value2 value5 value8
# 5 individual2 subset2 value11 value14 value17
# 6 individual2 subset3 value20 value23 value26
# 7 individual3 subset1 value3 value6 value9
# 8 individual3 subset2 value12 value15 value18
# 9 individual3 subset3 value21 value24 value27
然而,人们似乎开始将tidyr
+ dplyr
视为重塑数据的下一个重点。我还没有在所有的管道上销售,但方法是:
library(dplyr)
# devtools::install_github("hadley/tidyr")
library(tidyr)
foo_data %>%
gather(vars, vals, subset1.var1:subset3.var3) %>%
separate(vars, into = c("subset", "var")) %>%
spread(var, vals)
# individuals subset var1 var2 var3
# 1 individual1 subset1 value1 value4 value7
# 2 individual1 subset2 value10 value13 value16
# 3 individual1 subset3 value19 value22 value25
# 4 individual2 subset1 value2 value5 value8
# 5 individual2 subset2 value11 value14 value17
# 6 individual2 subset3 value20 value23 value26
# 7 individual3 subset1 value3 value6 value9
# 8 individual3 subset2 value12 value15 value18
# 9 individual3 subset3 value21 value24 value27
# Warning message:
# attributes are not identical across measure variables; they will be dropped