重塑 1 列中的值并附加到现有列名称
Reshape values from 1 column and attach to existing column name
我有一个如下所示的数据集:
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
我们可以使用 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
使用数据 table。我正在展示问题中发布的两个不同数据的解决方案。
library('data.table')
数据-1:
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
数据-2:
df2 <- 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 2 1 50 130
B 2 2 60 140
B 2 3 70 150
B 2 4 80 160', header = TRUE)
setDT(df2)
value.var <- names(df2)[!names(df2) %in% c('Col1', 'Col2', 'Col3')]
dcast(df2, Col2 + Col3 ~ Col1, value.var = value.var )
# Col2 Col3 Col5_A Col5_B Col4_A Col4_B
# 1: 1 1 90 NA 10 NA
# 2: 1 2 100 NA 20 NA
# 3: 1 3 110 NA 30 NA
# 4: 1 4 120 NA 40 NA
# 5: 2 1 NA 130 NA 50
# 6: 2 2 NA 140 NA 60
# 7: 2 3 NA 150 NA 70
# 8: 2 4 NA 160 NA 80
这是一个基本的 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))
此处,model.matrix
中的公式用于构建您想要的结构。末尾的 -1
确保显示每个级别的交互。因为函数returns是一个矩阵,所以用as.data.frame
转换一下。然后使用 sub
和正则表达式更改交互变量的名称。这个returns
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>
我有一个如下所示的数据集:
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
我们可以使用 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
使用数据 table。我正在展示问题中发布的两个不同数据的解决方案。
library('data.table')
数据-1:
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
数据-2:
df2 <- 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 2 1 50 130
B 2 2 60 140
B 2 3 70 150
B 2 4 80 160', header = TRUE)
setDT(df2)
value.var <- names(df2)[!names(df2) %in% c('Col1', 'Col2', 'Col3')]
dcast(df2, Col2 + Col3 ~ Col1, value.var = value.var )
# Col2 Col3 Col5_A Col5_B Col4_A Col4_B
# 1: 1 1 90 NA 10 NA
# 2: 1 2 100 NA 20 NA
# 3: 1 3 110 NA 30 NA
# 4: 1 4 120 NA 40 NA
# 5: 2 1 NA 130 NA 50
# 6: 2 2 NA 140 NA 60
# 7: 2 3 NA 150 NA 70
# 8: 2 4 NA 160 NA 80
这是一个基本的 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))
此处,model.matrix
中的公式用于构建您想要的结构。末尾的 -1
确保显示每个级别的交互。因为函数returns是一个矩阵,所以用as.data.frame
转换一下。然后使用 sub
和正则表达式更改交互变量的名称。这个returns
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>