重塑1列中的值并附加到现有列名称

时间:2018-05-09 20:48:25

标签: 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       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

2 个答案:

答案 0 :(得分:3)

我们可以使用gather中的unitespreadtidyr

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.matrixsub的基本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>