我正在使用
fastDummies
生成带有虚拟变量的数据框,以便稍后使用两个字符变量进行建模。
原来的样子是这样的:
PID Flag1 Flag2 Var_1 Var_2
0001 0 0 AB AB
0001 0 0 CD CD
0001 1 0 EF EF
0001 0 0 GH GH
0001 0 0 IJ IJ
0001 0 1 KL KL
0001 0 0 MN MN
0001 1 0 OP OP
0001 0 0 QR QR
0001 0 1 ST ST
0001 0 0 UV UV
0001 1 0 WX WX
0001 0 0 YZ YZ
并且
fastDummies
将生成 Var_1
和 Var_2
的输出,如下所示:
PID Flag1 Flag2 Var_1 Var_2 Var_1_AB Var_1_CD Var_1_EF Var_1_GH Var_1_IJ Var_1_KL Var_1_MN Var_1_OP Var_1_QR Var_1_ST Var_1_UV Var_1_WX Var_1_YZ Var_2_AB Var_2_CD Var_2_EF Var_2_GH Var_2_IJ Var_2_KL Var_2_MN Var_2_OP Var_2_QR Var_2_ST Var_2_UV Var_2_WX Var_2_YZ
0001 0 0 AB AB 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0001 0 0 CD CD 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
0001 1 0 EF EF 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
0001 0 0 GH GH 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
0001 0 0 IJ IJ 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
0001 0 1 KL KL 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
0001 0 0 MN MN 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
0001 1 0 OP OP 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
0001 0 0 QR QR 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
0001 0 1 ST ST 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
0001 0 0 UV UV 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
0001 1 0 WX WX 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0001 0 0 YZ YZ 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1
但是,数据包含用于编码变量是否需要反转的标志(在本例中,从 0 翻转到 1 或相反),用
Flag_1
和 Flag_2
表示。
需要看起来像这样:
PID Flag1 Flag2 Var_1 Var_2 Var_1_AB Var_1_CD Var_1_EF Var_1_GH Var_1_IJ Var_1_KL Var_1_MN Var_1_OP Var_1_QR Var_1_ST Var_1_UV Var_1_WX Var_1_YZ Var_2_AB Var_2_CD Var_2_EF Var_2_GH Var_2_IJ Var_2_KL Var_2_MN Var_2_OP Var_2_QR Var_2_ST Var_2_UV Var_2_WX Var_2_YZ
1 0 0 AB AB 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 CD CD 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
1 1 0 EF EF 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
1 0 0 GH GH 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
1 0 0 IJ IJ 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
1 0 1 KL KL 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 MN MN 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
1 1 0 OP OP 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
1 0 0 QR QR 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
1 0 1 ST ST 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 UV UV 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
1 1 0 WX WX 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
1 0 0 YZ YZ 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1
其中
Flag_1
上的 1 表示使用 Var_1
创建的虚拟变量从 0 翻转到 1,Flag_2
上的 1 表示使用 Var_2
创建的虚拟变量从 0 翻转到 1。
我最初打算创建一个函数来执行此操作,该函数读取数据帧并根据字符串和列名称解析值,然后通过
lapply
部署它,但我觉得有一种方法可以通过 使用
dplyr/tidyverse
来做到这一点mutate_at
或 mutate_all
可以使用我刚刚缺少的标准变量名称进行操作。
任何关于如何以更简单的方式完成此任务的建议将不胜感激。
生成上述数据框的一些代码:
list.of.packages <-
c("data.table", "tidyverse", "stringr","janitor","fastDummies")
new.packages <-
list.of.packages[!(list.of.packages %in% installed.packages()[, "Package"])]
if (length(new.packages))
install.packages(new.packages)
lapply(list.of.packages, require, character.only = TRUE)
df = data.frame(PID = c(0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001), Flag1 = c(0,0,1,0,0,0,0,1,0,0,0,1,0), Flag2 = c(0,0,0,0,0,1,0,0,0,1,0,0,0), Var_1 = c("AB","CD","EF","GH","IJ","KL","MN","OP","QR","ST","UV","WX","YZ"), Var_2 = c("AB","CD","EF","GH","IJ","KL","MN","OP","QR","ST","UV","WX","YZ"))
df <- dummy_cols(df, select_columns = "Var_1", remove_selected_columns=FALSE, omit_colname_prefix=FALSE)
df <- dummy_cols(df, select_columns = "Var_2", remove_selected_columns=FALSE, omit_colname_prefix=FALSE)
尝试两种
across
方法:
library(dplyr)
dat1new <- dat1 %>%
mutate(
across(starts_with("Var_1_"),
~ if_else(Var_1 == sub(".*_", "", cur_column()) & Flag1 > 0, +!., .)),
across(starts_with("Var_2_"),
~ if_else(Var_2 == sub(".*_", "", cur_column()) & Flag2 > 0, +!., .))
)
dat1new
# PID Flag1 Flag2 Var_1 Var_2 Var_1_AB Var_1_CD Var_1_EF Var_1_GH Var_1_IJ Var_1_KL Var_1_MN Var_1_OP Var_1_QR Var_1_ST Var_1_UV Var_1_WX Var_1_YZ Var_2_AB Var_2_CD Var_2_EF Var_2_GH Var_2_IJ Var_2_KL Var_2_MN Var_2_OP Var_2_QR Var_2_ST Var_2_UV Var_2_WX Var_2_YZ
# 1 1 0 0 AB AB 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
# 2 1 0 0 CD CD 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
# 3 1 1 0 EF EF 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
# 4 1 0 0 GH GH 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
# 5 1 0 0 IJ IJ 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
# 6 1 0 1 KL KL 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
# 7 1 0 0 MN MN 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
# 8 1 1 0 OP OP 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
# 9 1 0 0 QR QR 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
# 10 1 0 1 ST ST 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
# 11 1 0 0 UV UV 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
# 12 1 1 0 WX WX 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
# 13 1 0 0 YZ YZ 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1
all.equal(dat1new, dat2)
# [1] TRUE
演练:
across
是优于 mutate_at
的首选方法,它应该看起来足够相似。_
中使用尾随 starts_with("Var_1_")
应仅匹配我们想要的列,并跳过文字 Var_1
列。sub(...)
将每个列名称转换为 Var_1
Var_1
)匹配并且设置Flag1
时,然后使用+!.
,这是将整数转换为逻辑整数、反转它,然后返回整数的快捷方式。_2_
变量重复数据:
dat1
是您的原始数据(第二个数据代码块),dat2
是您想要的输出(第三个数据代码块)。
dat1 <- structure(list(PID = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), Flag1 = c(0L, 0L, 1L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 1L, 0L), Flag2 = c(0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 1L, 0L, 0L, 0L), Var_1 = c("AB", "CD", "EF", "GH", "IJ", "KL", "MN", "OP", "QR", "ST", "UV", "WX", "YZ"), Var_2 = c("AB", "CD", "EF", "GH", "IJ", "KL", "MN", "OP", "QR", "ST", "UV", "WX", "YZ"), Var_1_AB = c(1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Var_1_CD = c(0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Var_1_EF = c(0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Var_1_GH = c(0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Var_1_IJ = c(0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Var_1_KL = c(0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Var_1_MN = c(0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L), Var_1_OP = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L), Var_1_QR = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L), Var_1_ST = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L), Var_1_UV = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L), Var_1_WX = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L), Var_1_YZ = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L), Var_2_AB = c(1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Var_2_CD = c(0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Var_2_EF = c(0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Var_2_GH = c(0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Var_2_IJ = c(0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Var_2_KL = c(0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Var_2_MN = c(0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L), Var_2_OP = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L), Var_2_QR = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L), Var_2_ST = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L), Var_2_UV = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L), Var_2_WX = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L), Var_2_YZ = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L)), class = "data.frame", row.names = c(NA, -13L))
dat2 <- structure(list(PID = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), Flag1 = c(0L, 0L, 1L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 1L, 0L), Flag2 = c(0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 1L, 0L, 0L, 0L), Var_1 = c("AB", "CD", "EF", "GH", "IJ", "KL", "MN", "OP", "QR", "ST", "UV", "WX", "YZ"), Var_2 = c("AB", "CD", "EF", "GH", "IJ", "KL", "MN", "OP", "QR", "ST", "UV", "WX", "YZ"), Var_1_AB = c(1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Var_1_CD = c(0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Var_1_EF = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Var_1_GH = c(0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Var_1_IJ = c(0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Var_1_KL = c(0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Var_1_MN = c(0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L), Var_1_OP = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Var_1_QR = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L), Var_1_ST = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L), Var_1_UV = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L), Var_1_WX = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Var_1_YZ = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L), Var_2_AB = c(1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Var_2_CD = c(0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Var_2_EF = c(0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Var_2_GH = c(0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Var_2_IJ = c(0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Var_2_KL = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Var_2_MN = c(0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L), Var_2_OP = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L), Var_2_QR = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L), Var_2_ST = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Var_2_UV = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L), Var_2_WX = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L), Var_2_YZ = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L)), class = "data.frame", row.names = c(NA, -13L))