我有一个如下所示的数据集:
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
如何重塑这个,以便将Col1中的值放在Col4中所有列的列名中?我的实际数据集有20列。
我希望我的最终输出看起来像这样:
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
答案 0 :(得分:3)
我们可以使用gather
中的unite
,spread
和tidyr
:
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
答案 1 :(得分:1)
以下是包含model.matrix
和sub
的基本R方法。
# 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))
此处,model.matrix
中的公式用于构建您想要的结构。最后的-1
确保每个级别的交互都会出现。因为函数返回一个矩阵,所以使用as.data.frame
进行转换。然后使用sub
和正则表达式来更改交互变量的名称。返回
dat
Col2 Col3 Col4A Col4B Col5A Col5B
1 1 1 10 0 90 0
2 1 2 20 0 100 0
3 1 3 30 0 110 0
4 1 4 40 0 120 0
5 1 1 0 50 0 130
6 1 2 0 60 0 140
7 1 3 0 70 0 150
8 1 4 0 80 0 160
请注意,如果您计划直接在模型中使用它,则可能不希望将其转换为data.frame。如果它保持矩阵,请将names(dat)
替换为colnames(dat)
。
使用sub("^.*(.):(.*)$", "\\2_\\1", names(dat))
包含下划线。
为了使第一部分更具动态性,您可以使用函数为model.matrix
函数创建公式,如下所示:
f <- function(x) as.formula(paste0("~ Col2 + Col3 + Col1:(",
paste(paste0("Col", x), collapse=" + "), ") -1"))
然后试一试,
f(4:7)
~Col2 + Col3 + Col1:(Col4 + Col5 + Col6 + Col7) - 1
<environment: 0x3d2b598>