【问题标题】:Using dplyr mutate_at to change specified list of variables with case_when statement使用 dplyr mutate_at 通过 case_when 语句更改指定的变量列表
【发布时间】:2020-07-17 14:04:56
【问题描述】:

我正在尝试重新编码数据集中的某些列。这些列有很多奇怪的名称,例如 S3__8 或 C4__2。还有一些以 C 开头的分类列,例如 Case。

我使用此段成功地重新编码了所有 S 列:

Sa_Recode <- Sa %>%
  mutate_at(vars(starts_with("S")),
    funs(case_when(grepl("Yes", ., ignore.case = TRUE) ~ "1",
                   grepl("No", ., ignore.case = TRUE) ~ "0",
                   grepl("Some", ., ignore.case = TRUE) ~ "0.5",
                   TRUE                                         ~ "Else")))

我想重新编码 C 列,但不能使用相同的逻辑,因为我的其他一些列以 C 开头。 我试过像这样编辑 mutate 行,但没有运气:

创建我需要的列的列表并制作列表

list <- c('C1_(*)__', 'C2_4__', 'C3_(*)__', 'C3a_(*)__') 
mutate_at(vars(list),

将它们列为变量

mutate_at(c('C1_(*)__', 'C2_4__', 'C3_(*)__', 'C3a_(*)__'),

将它们作为变量以不同的方式列出

mutate_at(vars(c('C1_(*)__', 'C2_4__', 'C3_(*)__', 'C3a_(*)__')),

调用一系列列

mutate_at(Sa[,8:53],

我将用其他大约九个集合(具有不同的起始字母)重复此过程,并希望学习如何操作逻辑。 或者,有没有办法让case语句中的“else”不重新编码值?这也可以解决问题。 谢谢!

Sample Input:
Case  S25_    S26_(*)__   C1_(*)__
A     No      Some        Yes
B     Yes     Skipped     Yes
C     No      N/A         Some

Desired output:
Case  S25_    S26_(*)__   C1_(*)__
A     0       0.5         1
B     1       Skipped     1
C     0       N/A         0.5

【问题讨论】:

  • 请包括一些代表性的输入和预期输出数据,例如使用dput

标签: r dplyr


【解决方案1】:

您可以使用正则表达式来正确识别要更改的列。

library(dplyr)
Sa %>%
  mutate_at(vars(matches('^S|C\\d+')),
             ~case_when(grepl("Yes", ., ignore.case = TRUE) ~ "1",
                        grepl("No", ., ignore.case = TRUE) ~ "0",
                        grepl("Some", ., ignore.case = TRUE) ~ "0.5",
                        TRUE ~ "Else"))

这将选择以"S" 开头或"C" 后跟数字的列。

此外,mutate_at 已替换为 across,因此您现在可以使用:

Sa %>%
   mutate(across(matches('^S|C\\d+'),
            ~case_when(grepl("Yes", ., ignore.case = TRUE) ~ "1",
                       grepl("No", ., ignore.case = TRUE) ~ "0",
                       grepl("Some", ., ignore.case = TRUE) ~ "0.5",
                       TRUE ~ "Else")))

【讨论】:

  • 谢谢!但是,这不适用于 C 列。我尝试将它分成两部分(一个先用 S mutate_at,然后先用 C 再用另一个 mutate_at,但它重新编码了 Case。
  • 不要拆分列。你能在names(Sa) 中展示你有什么吗?
  • "Case_First_Name" [7] "Case_Last_Name" "S5_()__" "S5a_()__" "S5b_" "Text...11" "S6_()__" [13] "S7_" "S8_()__" "S9_()__" "S10_" "文本...17" "S11_()__" [19] "S12_()__" "S12a_()__" "S13_()__" "S14_()__" "文本...23" "S15_ ()__" [37] "S24_()__" "S25_" "S26_()__" "C1_()__" "C2_()__ " "S18_()__" [49] "S3_()__" "文本...50" "S4_()__" "C3_()__" " C3a_()__" "CASE_P"
  • 是的,您可以使用|添加不同的模式组合。
  • 您也可以在mutate_at 中按位置指定列:Sa %&gt;% mutate_at(12:ncol(df), ....rest of the code
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-03
  • 2021-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多