循环 data.frame 列以在 R 中生成虚拟变量
Loop over data.frame columns to generate dummy variable in R
我正在努力为我当前的项目生成一个变量。我在 Windows.
上使用 R 版本 4.0.1
数据说明
我在 data.table
中有不平衡的面板数据,其中包含 243 个变量(在 运行 命令之前)和 8,278 个观察值。数据由 ID
和 period
唯一标识。此外,在 69:135
列中,我得到了不同的地区虚拟变量(2= 是,公司在该地区运营;1= 否,公司不在该地区运营),在 178:244
列中,我得到了相同变量的滞后版本来自按 ID 分组的 69:135
列。这是数据的一个小例子:
dat <-
data.table(id = as.factor(c(rep("C001", 3), "C002", rep("C003", 5), rep("C004", 2), rep("C005", 7))),
period = as.factor(c(1, 2, 3, 2, 1, 4, 5, 6, 10, 3, 4, 2, 3, 4, 7, 8, 9, 10)),
region1 = as.factor(c(NA, NA, 2, 1, NA, 1, 2, 2, 1, NA, 1, rep(NA, 7))),
region2 = as.factor(c(1, 2, 1, 1, NA, NA, 2, 1, 2, 1, 1, rep(NA, 7))),
industry = as.factor(c(rep("Finance", 3), "Culture", rep("Nutrition", 5), rep("Finance", 2), rep("Medicine", 7))),
number_employees = as.numeric(c(10, 10, 12, 2, 2, 4, 4, 4, 4, 18, 25, 100, 110, 108, 108, 120, 120, 120)),
lag_region1 = as.factor(c(rep(NA, 6), 1, 2, 2, rep(NA, 9))),
lag_region2 = as.factor(c(NA, 1, 2, rep(NA, 4), 2, 1, NA, 1, rep(NA, 7))))
#this gives (last 8 rows are not printed):
# id period region1 region2 industry number_employees lag_region1 lag_region2
# 1: C001 1 <NA> 1 Finance 10 <NA> <NA>
# 2: C001 2 <NA> 2 Finance 10 <NA> 1
# 3: C001 3 2 1 Finance 12 <NA> 2
# 4: C002 2 1 1 Culture 2 <NA> <NA>
# 5: C003 1 <NA> <NA> Nutrition 2 <NA> <NA>
# 6: C003 4 1 <NA> Nutrition 4 <NA> <NA>
# 7: C003 5 2 2 Nutrition 4 1 <NA>
# 8: C003 6 2 1 Nutrition 4 2 2
# 9: C003 10 1 2 Nutrition 4 2 1
#10: C004 3 <NA> 1 Finance 18 <NA> <NA>
期望的结果
我想生成一个新的虚拟变量 left_region
,当一家公司在相应时期至少离开一个地区时,它等于“是”。我想通过“比较”第 69 列与第 178 列、第 70 列与第 179 列、第 71 列与第 180 列等来解决此问题。 dt[, 69] == 1 & dt[, 178] == 2
(因此,如果公司离开其之前运营的地区,left_region
等于“是”)。期望的结果如下所示:
# desired result (last 8 rows are not printed):
# id period region1 region2 industry number_employees lag_region1 lag_region2 left_region
# 1: C001 1 <NA> 1 Finance 10 <NA> <NA> no
# 2: C001 2 <NA> 2 Finance 10 <NA> 1 no
# 3: C001 3 2 1 Finance 12 <NA> 2 yes
# 4: C002 2 1 1 Culture 2 <NA> <NA> no
# 5: C003 1 <NA> <NA> Nutrition 2 <NA> <NA> no
# 6: C003 4 1 <NA> Nutrition 4 <NA> <NA> no
# 7: C003 5 2 2 Nutrition 4 1 <NA> no
# 8: C003 6 2 1 Nutrition 4 2 2 yes
# 9: C003 10 1 2 Nutrition 4 2 1 yes
#10: C004 3 <NA> 1 Finance 18 <NA> <NA> no
问题描述
不过,我正在努力为所有观察一次获得这个 运行。我在 for
循环中使用 ifelse()
进行了尝试。为此,我必须先制作 data.table
a data.frame
。
# generate empty cells
df <- data.frame(matrix(NA, nrow = 8278, ncol = 67))
# combine prior data.table and new data.frame in large data.frame (with data.table the following loop does not work)
dt <- as.data.frame(cbind(dt, df))
# loop through 67 columns comparing 69 to 178, 70 to 179, etc.
for (i in 69:135) {
dt[, i + 176] <- ifelse(is.na(dt[, i]) & is.na(dt[, (i + 109)]), NA,
ifelse(dt[, i] == 1 & dt[, (i + 109)] == 2, "yes", "no"
)
)
}
# generate final dummy variable left_region --> there is some error here
dt$left_region <-
ifelse(any(dt[, c(245:311)] == "yes"), "yes", "no")
然而,运行 最后一个 ifelse()
与 any()
结合,导致 left_region
仅包含 8,278 个观察结果中的每一个的“是”。
我测试了后一个 ifelse()
命令在仅使用一次观察时的行为方式。
#take out one observation
one_row <- dt[7, ]
library(dplyr)
# generate left_region for one observation only
new <-
one_row %>%
mutate(left_region = ifelse(any(one_row[, c(245:311)] == "yes"), "yes", "no"))
选择的观察应该生成 left_region
== "no" 但在这种情况下它的作用恰恰相反。似乎最后一个 ifelse()
参数“no”没有被 R 注册。
除了不是问题的“漂亮”解决方案之外,将 ifelse()
和 any()
的组合放入 for()
循环中也不能解决问题。在这种情况下,left_region
仅在 270 种情况下表示“是”,但永远不会表示“否”。
for (i in 1:nrow(dt)) {
dt$left_region[i] <-
ifelse(any(dt[i, c(245:311)] == "yes"), "yes", "no")
}
有谁知道为什么会这样?我需要做什么才能收到我想要的结果?非常感谢任何想法!
我非常希望我能以通俗易懂的方式解释所有内容。
非常感谢!
如果 69:135 列中的值为 1,dt[, 69:135] == 1
将 return TRUE
,否则 FALSE
。
如果 178:244 列中的值为 2,dt[, 178:244] == 2
将 return TRUE
,否则 FALSE
。
您可以在它们之间执行 AND (&
) 运算以逐元素比较它们,意思是 dt[, 69] & dt[, 178]
、dt[, 70] & dt[, 179]
等等。将它们按行求和并将其标记为 'Yes'
,即使在该行中找到单个 TRUE
。
dt$left_region <- ifelse(rowSums(dt[, 69:135] == 1 & dt[, 178:244] == 2) > 0, 'yes', 'no')
我正在努力为我当前的项目生成一个变量。我在 Windows.
上使用 R 版本 4.0.1数据说明
我在 data.table
中有不平衡的面板数据,其中包含 243 个变量(在 运行 命令之前)和 8,278 个观察值。数据由 ID
和 period
唯一标识。此外,在 69:135
列中,我得到了不同的地区虚拟变量(2= 是,公司在该地区运营;1= 否,公司不在该地区运营),在 178:244
列中,我得到了相同变量的滞后版本来自按 ID 分组的 69:135
列。这是数据的一个小例子:
dat <-
data.table(id = as.factor(c(rep("C001", 3), "C002", rep("C003", 5), rep("C004", 2), rep("C005", 7))),
period = as.factor(c(1, 2, 3, 2, 1, 4, 5, 6, 10, 3, 4, 2, 3, 4, 7, 8, 9, 10)),
region1 = as.factor(c(NA, NA, 2, 1, NA, 1, 2, 2, 1, NA, 1, rep(NA, 7))),
region2 = as.factor(c(1, 2, 1, 1, NA, NA, 2, 1, 2, 1, 1, rep(NA, 7))),
industry = as.factor(c(rep("Finance", 3), "Culture", rep("Nutrition", 5), rep("Finance", 2), rep("Medicine", 7))),
number_employees = as.numeric(c(10, 10, 12, 2, 2, 4, 4, 4, 4, 18, 25, 100, 110, 108, 108, 120, 120, 120)),
lag_region1 = as.factor(c(rep(NA, 6), 1, 2, 2, rep(NA, 9))),
lag_region2 = as.factor(c(NA, 1, 2, rep(NA, 4), 2, 1, NA, 1, rep(NA, 7))))
#this gives (last 8 rows are not printed):
# id period region1 region2 industry number_employees lag_region1 lag_region2
# 1: C001 1 <NA> 1 Finance 10 <NA> <NA>
# 2: C001 2 <NA> 2 Finance 10 <NA> 1
# 3: C001 3 2 1 Finance 12 <NA> 2
# 4: C002 2 1 1 Culture 2 <NA> <NA>
# 5: C003 1 <NA> <NA> Nutrition 2 <NA> <NA>
# 6: C003 4 1 <NA> Nutrition 4 <NA> <NA>
# 7: C003 5 2 2 Nutrition 4 1 <NA>
# 8: C003 6 2 1 Nutrition 4 2 2
# 9: C003 10 1 2 Nutrition 4 2 1
#10: C004 3 <NA> 1 Finance 18 <NA> <NA>
期望的结果
我想生成一个新的虚拟变量 left_region
,当一家公司在相应时期至少离开一个地区时,它等于“是”。我想通过“比较”第 69 列与第 178 列、第 70 列与第 179 列、第 71 列与第 180 列等来解决此问题。 dt[, 69] == 1 & dt[, 178] == 2
(因此,如果公司离开其之前运营的地区,left_region
等于“是”)。期望的结果如下所示:
# desired result (last 8 rows are not printed):
# id period region1 region2 industry number_employees lag_region1 lag_region2 left_region
# 1: C001 1 <NA> 1 Finance 10 <NA> <NA> no
# 2: C001 2 <NA> 2 Finance 10 <NA> 1 no
# 3: C001 3 2 1 Finance 12 <NA> 2 yes
# 4: C002 2 1 1 Culture 2 <NA> <NA> no
# 5: C003 1 <NA> <NA> Nutrition 2 <NA> <NA> no
# 6: C003 4 1 <NA> Nutrition 4 <NA> <NA> no
# 7: C003 5 2 2 Nutrition 4 1 <NA> no
# 8: C003 6 2 1 Nutrition 4 2 2 yes
# 9: C003 10 1 2 Nutrition 4 2 1 yes
#10: C004 3 <NA> 1 Finance 18 <NA> <NA> no
问题描述
不过,我正在努力为所有观察一次获得这个 运行。我在 for
循环中使用 ifelse()
进行了尝试。为此,我必须先制作 data.table
a data.frame
。
# generate empty cells
df <- data.frame(matrix(NA, nrow = 8278, ncol = 67))
# combine prior data.table and new data.frame in large data.frame (with data.table the following loop does not work)
dt <- as.data.frame(cbind(dt, df))
# loop through 67 columns comparing 69 to 178, 70 to 179, etc.
for (i in 69:135) {
dt[, i + 176] <- ifelse(is.na(dt[, i]) & is.na(dt[, (i + 109)]), NA,
ifelse(dt[, i] == 1 & dt[, (i + 109)] == 2, "yes", "no"
)
)
}
# generate final dummy variable left_region --> there is some error here
dt$left_region <-
ifelse(any(dt[, c(245:311)] == "yes"), "yes", "no")
然而,运行 最后一个 ifelse()
与 any()
结合,导致 left_region
仅包含 8,278 个观察结果中的每一个的“是”。
我测试了后一个 ifelse()
命令在仅使用一次观察时的行为方式。
#take out one observation
one_row <- dt[7, ]
library(dplyr)
# generate left_region for one observation only
new <-
one_row %>%
mutate(left_region = ifelse(any(one_row[, c(245:311)] == "yes"), "yes", "no"))
选择的观察应该生成 left_region
== "no" 但在这种情况下它的作用恰恰相反。似乎最后一个 ifelse()
参数“no”没有被 R 注册。
除了不是问题的“漂亮”解决方案之外,将 ifelse()
和 any()
的组合放入 for()
循环中也不能解决问题。在这种情况下,left_region
仅在 270 种情况下表示“是”,但永远不会表示“否”。
for (i in 1:nrow(dt)) {
dt$left_region[i] <-
ifelse(any(dt[i, c(245:311)] == "yes"), "yes", "no")
}
有谁知道为什么会这样?我需要做什么才能收到我想要的结果?非常感谢任何想法!
我非常希望我能以通俗易懂的方式解释所有内容。 非常感谢!
dt[, 69:135] == 1
将 return TRUE
,否则 FALSE
。
dt[, 178:244] == 2
将 return TRUE
,否则 FALSE
。
您可以在它们之间执行 AND (&
) 运算以逐元素比较它们,意思是 dt[, 69] & dt[, 178]
、dt[, 70] & dt[, 179]
等等。将它们按行求和并将其标记为 'Yes'
,即使在该行中找到单个 TRUE
。
dt$left_region <- ifelse(rowSums(dt[, 69:135] == 1 & dt[, 178:244] == 2) > 0, 'yes', 'no')