【问题标题】:How to apply ifelse function across multiple columns and create new columns in R如何跨多个列应用 ifelse 函数并在 R 中创建新列
【发布时间】:2021-05-13 14:25:38
【问题描述】:

我想在我的数据集的多个列中应用 ifelse 函数并创建新的“重新评分”列。这是一个示例数据集:

data = data.frame(year = "2021",
                  month = sample(x = c(1:12), size = 10, replace = TRUE),
                  C1 = sample(x = c('Off', 'Yes'), size = 10, replace = TRUE),
                  C2 = sample(x = c('Off', 'Yes'), size = 10, replace = TRUE),
                  C3 = sample(x = c('Off', 'Yes'), size = 10, replace = TRUE),
                  C4 = sample(x = c('Off', 'Yes'), size = 10, replace = TRUE),
                  C5 = sample(x = c('Off', 'Yes'), size = 10, replace = TRUE),
                  C6 = sample(x = c('Off', 'Yes'), size = 10, replace = TRUE),
                  C7 = sample(x = c('Off', 'Yes'), size = 10, replace = TRUE),
                  C8 = sample(x = c('Off', 'Yes'), size = 10, replace = TRUE),
                  C9 = sample(x = c('Off', 'Yes'), size = 10, replace = TRUE),
                  C10 = sample(x = c('Off', 'Yes'), size = 10, replace = TRUE))

我想在所有以 C: 开头的行中应用这样的函数:

rescored = data %>%
  mutate(T1 = ifelse(C1 == "Off", 1,
                     ifelse(C1 == "Yes", 0, NA)))

我的真实数据集有 50 行或更多行需要应用此函数。有没有一种简单的方法可以做到这一点?我已经尝试在 dplyr 中使用“across”的变体,如下所示,但没有成功。我敢肯定还有一个“应用”选项。

rescored = data %>%
  mutate(across(C1:C50, ifelse(~ .x == "Off", 1,
                               ifelse(~.x == "Yes", 0, NA))))

【问题讨论】:

    标签: r function if-statement dplyr across


    【解决方案1】:

    只需这样做(您必须在函数语句的开头使用twiddle~,而不是在每个参数之前。)

    data %>%
      mutate(across(starts_with('C'), ~ifelse( .x == "Off", 1,
                                   ifelse(.x == "Yes", 0, NA))))
    
       year month C1 C2 C3 C4 C5 C6 C7 C8 C9 C10
    1  2021     1  1  0  0  1  1  0  0  1  1   1
    2  2021    12  1  1  0  0  1  1  1  0  1   0
    3  2021    10  1  0  1  0  0  1  0  0  1   1
    4  2021     3  0  1  1  1  0  1  0  0  0   1
    5  2021    11  1  0  1  1  1  0  1  0  0   0
    6  2021    12  1  0  0  1  1  1  0  0  1   0
    7  2021     4  0  0  0  1  1  0  1  0  1   0
    8  2021     2  0  0  0  1  0  0  0  0  1   0
    9  2021     3  0  0  1  0  0  1  0  0  1   0
    10 2021     9  1  0  0  0  0  0  1  0  0   0
    

    如果您想保留原始列,也许可以这样做

    
    data %>%
      mutate(across(starts_with('C'), ~ifelse( .x == "Off", 1, 0), .names = 'scr_{sub("C", "", .col)}'))
    #>    year month  C1  C2  C3  C4  C5  C6  C7  C8  C9 C10 scr_1 scr_2 scr_3 scr_4
    #> 1  2021     7 Yes Yes Yes Off Yes Off Off Yes Yes Yes     0     0     0     1
    #> 2  2021    11 Off Yes Yes Yes Yes Yes Off Yes Yes Yes     1     0     0     0
    #> 3  2021     1 Yes Yes Off Off Yes Yes Yes Off Yes Yes     0     0     1     1
    #> 4  2021     5 Yes Off Off Yes Yes Yes Yes Off Yes Yes     0     1     1     0
    #> 5  2021     6 Off Off Yes Yes Off Off Off Yes Off Yes     1     1     0     0
    #> 6  2021    12 Yes Yes Yes Off Off Yes Yes Yes Off Yes     0     0     0     1
    #> 7  2021     1 Off Off Off Off Yes Off Off Off Yes Yes     1     1     1     1
    #> 8  2021     1 Yes Yes Yes Off Off Yes Yes Off Off Yes     0     0     0     1
    #> 9  2021     8 Off Yes Off Yes Off Off Yes Yes Yes Yes     1     0     1     0
    #> 10 2021    10 Off Yes Off Yes Yes Off Off Yes Off Off     1     0     1     0
    #>    scr_5 scr_6 scr_7 scr_8 scr_9 scr_10
    #> 1      0     1     1     0     0      0
    #> 2      0     0     1     0     0      0
    #> 3      0     0     0     1     0      0
    #> 4      0     0     0     1     0      0
    #> 5      1     1     1     0     1      0
    #> 6      1     0     0     0     1      0
    #> 7      0     1     1     1     0      0
    #> 8      1     0     0     1     1      0
    #> 9      1     1     0     0     0      0
    #> 10     0     1     1     0     1      1
    

    reprex package (v2.0.0) 于 2021-05-15 创建

    【讨论】:

    • 很高兴它有帮助。也请考虑an upvote。对于每个问题,您可以为您认为正确的答案投票。
    【解决方案2】:

    以下选项似乎有效。我不确定是否有更优雅的方式来做到这一点。在第二步中重命名变量似乎并不理想。

    rescore <- function(x, na.rm = FALSE) (ifelse(x == "Off", 1, ifelse(x == "Yes", 0, NA)))
                                           
    data %>% 
      mutate_at(c(as.vector(paste0("C", 1:50))), funs(scr = rescore)) %>%
      rename_at(vars(ends_with("_scr")), funs(paste("scr", 1:50, sep = "_")))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-22
      • 2018-12-23
      • 2021-11-17
      • 1970-01-01
      • 2021-11-01
      • 2021-02-11
      • 2017-09-29
      • 2018-10-13
      相关资源
      最近更新 更多