【问题标题】:Combining two dummy variables into a new one将两个虚拟变量组合成一个新变量
【发布时间】:2021-11-08 23:12:09
【问题描述】:

我有 2 个虚拟变量

  1. physical_violence
  2. sexual_violence

我尝试将它们与ifelse() 函数和|-operator 结合起来创建一个虚拟变量,如果至少发生了一次暴力,该变量返回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 起暴力事件。

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

【问题讨论】:

  • 如果您包含一个简单的reproducible example,其中包含可用于测试和验证可能解决方案的示例输入和所需输出,则更容易为您提供帮助。
  • 要获得 1480 起暴力案例,您必须 SUM 两列中 1 的总数,而使用您的代码,您正在对存在两种形式的暴力的所有行求和。
  • 如果一个对象对两种暴力类型都呈阳性,你认为这是一两个暴力案例吗?您的代码说它是 1,但这个预期的 1480 计数另有说明

标签: r if-statement categorical-data dummy-variable


【解决方案1】:

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

示例数据框:

# 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-loop + 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 包于 2021-09-13 创建 (v2.0.1)

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

【讨论】:

    【解决方案2】:

    只要我们有可以简化为每行单个 TRUE/FALSE 的逐行逻辑运算,我们就可以使用 dplyr::if_anydplyr::if_all
    -) 第一个mutate()if_any 的变量名称为matches,正则表达式"e03[b-j]idummy".x==1,physical_violence 将为+TRUE(计算结果为1)。
    -) 第二个mutate 使用类似的逻辑,以及您提供的其他参数。
    -) 第三个变异将输出 1 if_any 其他两个新列是 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')))
    

    【讨论】:

    • 奥布里加达!这是我所做的更简单的方法。关于你的另一条评论,如果一个主题对这两种暴力是正面的,我认为它只是一个案例。这正好解决了我的误解。
    猜你喜欢
    • 2018-10-23
    • 1970-01-01
    • 2012-08-10
    • 1970-01-01
    • 2012-01-15
    • 2018-03-22
    相关资源
    最近更新 更多