将两个虚拟变量组合成一个新变量

Combining two dummy variables into a new one

我有 2 个虚拟变量

  1. physical_violence
  2. sexual_violence.

我试图将它们与 ifelse() 函数和 | 运算符结合起来创建一个虚拟变量,如果至少发生了一次暴力事件,则 returns 1。 以下方法输出不同的结果:

df <- mutate(df, physical_violence = iffelse(e03bidummy == 1 | e03cidummy == 1 |
e03didummy == 1 | e03eidummy == 1 | e03fidummy == 1 | 
e03gidummy == 1 | e03hidummy == 1 | e03iidummy == 1 | 
e03jidummy == 1, 1, 0)) 
df <- mutate(df, sexual_violence = ifelse(e04aidummy == 1 | 
e04bidummy == 1 | e04cidummy == 1 | e04didummy == 1, 1, 0))

结合上述两个变量的虚拟代码:

df <- mutate(df, physical_sexual_violence = 
ifelse(physical_violence == 1 | sexual_violence == 1, 1, 0))

我从中得到的结果是: table(df$physical_sexual_violence): # 875 “是”, 26.614 “否”` 这与以下矛盾:

  1. table(df$physical_violence):# 846 个“是”(3.07%)和 26.643 个“否”
  2. table(df$sexual_violence) # 634 个“是”和 26.855 个“否”。

我预计会有 1.480 起暴力案件。

谁能帮我找出我做错了什么?

这有帮助吗?当然你需要适应你的变量名。

示例数据框:

# just a synthetic sample dataframe
df <- data.frame(physical_violence = c(0, 0, 1, 0, 1), # assuming no NAs
                 sexual_violence = c(0, 1, 1, 1, 0)) # assuming no NAs 

for循环+if-else语句:

for(i in 1:nrow(df)){
  df$dummy[i] <- NA
  if(df$physical_violence[i]== 0 & df$sexual_violence[i]== 0) { 
    df$dummy[i] <- FALSE
  } else {
    df$dummy[i] <- TRUE
  }
}

输出:

df
#>   physical_violence sexual_violence dummy
#> 1                 0               0 FALSE
#> 2                 0               1  TRUE
#> 3                 1               1  TRUE
#> 4                 0               1  TRUE
#> 5                 1               0  TRUE

由 reprex 包 (v2.0.1) 创建于 2021-09-13

请注意,这种方法既不是最快的也不是最安全的方法,但语法对于初学者来说很容易理解。 编辑:如果您需要 0-1,只需将 TRUE 替换为 1,将 FALSE 替换为 0。(如果需要,请不要忘记将 df$dummy 更改为因子变量。)

每当我们有可以简化为每行单个 TRUE/FALSE 的按行逻辑运算时,我们可以使用 dplyr::if_anydplyr::if_all.
-) 第一个 mutate()if_any 的变量名称 matches 正则表达式 "e03[b-j]idummy",是 .x==1,physical_violence 将是 +TRUE(计算结果为 1)。
-) 第二个 mutate 使用类似的逻辑,使用您提供的其他参数。
-) 第三个 mutate 将输出 1 if_any of other two new columns is 1.

虚拟数据

  e03bidummy e03cidummy e04aidummy e04bidummy
1          1          0          0          0
2          0          1          0          0
3          0          0          1          1
4          0          0          0          0

dplyr 解决方案

library(dplyr)

df %>% mutate(physical_violence = +if_any(matches("e03[b-j]idummy"), ~.x==1),
              sexual_violence = +if_any(matches("e04[a-d]idummy"), ~.x==1),
              physical_sexual_violence= +if_any(contains('violence')))

  e03bidummy e03cidummy e04aidummy e04bidummy physical_violence sexual_violence physical_sexual_violence
1          1          0          0          0                 1               0                        1
2          0          1          0          0                 1               0                        1
3          0          0          1          1                 0               1                        1
4          0          0          0          0                 0               0                        0

如果所有虚拟变量都严格为 0 或 1,则可以进一步简化代码,省略 .x==1 部分,因为逻辑在求和运算期间被隐式强制为 1/0:

df %>% mutate(physical_violence = +if_any(matches("e03[b-j]idummy")),
              sexual_violence = +if_any(matches("e04[a-d]idummy")),
              physical_sexual_violence= +if_any(contains('violence')))