R 重塑1列中的值并附加到现有列名
我的数据集如下所示:R 重塑1列中的值并附加到现有列名,r,reshape,melt,R,Reshape,Melt,我的数据集如下所示: Col1 Col2 Col3 Col4 Col5 A 1 1 10 90 A 1 2 20 100 A 1 3 30 110 A 1 4 40 120 B 2 1 50 130 B 2
Col1 Col2 Col3 Col4 Col5
A 1 1 10 90
A 1 2 20 100
A 1 3 30 110
A 1 4 40 120
B 2 1 50 130
B 2 2 60 140
B 2 3 70 150
B 2 4 80 160
Col2 Col3 Col4_A Col4_B Col5_A Col5_B
1 1 10 NA 90 NA
1 2 20 NA 100 NA
1 3 30 NA 110 NA
1 4 40 NA 120 NA
2 1 NA 50 NA 130
2 2 NA 60 NA 140
2 3 NA 70 NA 150
2 4 NA 80 NA 160
我如何重新设置它的形状,使Col1中的值位于Col4及以后所有列的列名中?我的实际数据集大约有20列
我希望我的最终输出如下所示:
Col1 Col2 Col3 Col4 Col5
A 1 1 10 90
A 1 2 20 100
A 1 3 30 110
A 1 4 40 120
B 2 1 50 130
B 2 2 60 140
B 2 3 70 150
B 2 4 80 160
Col2 Col3 Col4_A Col4_B Col5_A Col5_B
1 1 10 NA 90 NA
1 2 20 NA 100 NA
1 3 30 NA 110 NA
1 4 40 NA 120 NA
2 1 NA 50 NA 130
2 2 NA 60 NA 140
2 3 NA 70 NA 150
2 4 NA 80 NA 160
我们可以从
tidyr
使用collect
、unite
和spread
:
library(dplyr)
library(tidyr)
df %>%
gather(var, value, -(Col1:Col3)) %>%
unite(var, var, Col1, sep="_") %>%
spread(var, value)
结果:
Col2 Col3 Col4_A Col4_B Col5_A Col5_B
1 1 1 10 NA 90 NA
2 1 2 20 NA 100 NA
3 1 3 30 NA 110 NA
4 1 4 40 NA 120 NA
5 2 1 NA 50 NA 130
6 2 2 NA 60 NA 140
7 2 3 NA 70 NA 150
8 2 4 NA 80 NA 160
df1 <- read.table(text='Col1 Col2 Col3 Col4 Col5
A 1 1 10 90
A 1 2 20 100
A 1 3 30 110
A 1 4 40 120
B 1 1 50 130
B 1 2 60 140
B 1 3 70 150
B 1 4 80 160', header = TRUE)
setDT(df1)
value.var <- names(df1)[!names(df1) %in% c('Col1', 'Col2', 'Col3')]
dcast(df1, Col2 + Col3 ~ Col1, value.var = value.var )
# Col2 Col3 Col5_A Col5_B Col4_A Col4_B
# 1: 1 1 90 130 10 50
# 2: 1 2 100 140 20 60
# 3: 1 3 110 150 30 70
# 4: 1 4 120 160 40 80
使用数据表。我展示了问题中发布的两个不同数据的解决方案
library('data.table')
数据-1:
Col2 Col3 Col4_A Col4_B Col5_A Col5_B
1 1 1 10 NA 90 NA
2 1 2 20 NA 100 NA
3 1 3 30 NA 110 NA
4 1 4 40 NA 120 NA
5 2 1 NA 50 NA 130
6 2 2 NA 60 NA 140
7 2 3 NA 70 NA 150
8 2 4 NA 80 NA 160
df1 <- read.table(text='Col1 Col2 Col3 Col4 Col5
A 1 1 10 90
A 1 2 20 100
A 1 3 30 110
A 1 4 40 120
B 1 1 50 130
B 1 2 60 140
B 1 3 70 150
B 1 4 80 160', header = TRUE)
setDT(df1)
value.var <- names(df1)[!names(df1) %in% c('Col1', 'Col2', 'Col3')]
dcast(df1, Col2 + Col3 ~ Col1, value.var = value.var )
# Col2 Col3 Col5_A Col5_B Col4_A Col4_B
# 1: 1 1 90 130 10 50
# 2: 1 2 100 140 20 60
# 3: 1 3 110 150 30 70
# 4: 1 4 120 160 40 80
df1这里是一个基本的R方法,使用model.matrix
和sub
# construct desired data.frame
dat <- as.data.frame(model.matrix(~Col2 + Col3 + Col1:(Col4 + Col5) - 1, df1))
# construct desired names
names(dat) <- sub("^.*(.):(.*)$", "\\2\\1", names(dat))
请注意,如果您计划在模型中直接使用此选项,则可能不希望将其转换为data.frame。如果它仍然是一个矩阵,则将names(dat)
替换为colnames(dat)
使用sub(“^.*(.):(.*)$”、“\\2\\\1”、名称(dat))
包含下划线
要使第一部分更具动态性,可以使用函数为model.matrix
函数创建公式,如下所示:
f <- function(x) as.formula(paste0("~ Col2 + Col3 + Col1:(",
paste(paste0("Col", x), collapse=" + "), ") -1"))
f我想最后一列应该叫做Col5\B
你说得对,我也要试试你的答案,谢谢!我更新了问题,使其更有意义。您更改了预期输出。。。这真的是您想要的,而不是之前的格式吗?是的,因为我的实际数据集将有一些示例,其中没有找到像上面那样的数据。希望这有意义!很抱歉更改了答案,希望您提供的答案在此场景中仍然有效。我认为您的预期输出不一致,因为Col4
中的50:80
最初出现在Col2==2
的行中。同样的问题也存在于Col5\u A
有没有办法不把它硬编码成两列而是df[,2]:ncol(df)?@nak5120不确定这是否回答了您的问题,但是您可以使用-(Col1:Col3)
来排除所有Col1
、Col2
和Col3
。请参见我的updatejust好奇,代码中的第一列被删除在哪里?只是想follow@nak5120在unite
步骤中,它被var
消耗掉了。unite
的默认值是remove=TRUE
,这将删除输入列。您还可以设置remove=FALSE
以保留它。谢谢!您是否能够使Col4、Col5不硬编码,而只是从4开始调用列?谢谢,是否可以使Col4和Col5不硬编码,而只是从df[,4]开始,因为我的实际数据集有20个左右的列?