如何将一个简单的函数应用于多个列?

How can I apply a simple function to multiple columns?

我有以下数据框:

df <- data.frame("A" = c("y", "y", "n", "n"),
             "B" = c("n", NA, "y", "y"),
             "C" = c("n", "y", "y", "n"))

我想将以下代码应用于 A 列和 B 列:

df$A <- 
  df$A %>% 
  recode(
    "n" = "No",
    "y" = "Yes"
  ) %>% 
  factor(
    levels = c("No", "Yes")
  )

我尝试使用以下代码使用 for 循环解决此问题:

cols <- c("A", "B")

for (i in cols) {
  df$i <- 
    df$i %>% 
    recode(
      "n" = "No",
      "y" = "Yes"
    ) %>% 
    factor(
      levels = c("No", "Yes")
    )
}

但是,我收到这条错误消息:

Error in UseMethod("recode") : 
  no applicable method for 'recode' applied to an object of class "NULL"

任何人都可以帮我解决我在这里遗漏的问题吗?感谢您的帮助!

使用 dplyr::across 你可以:

library(dplyr)

df <- data.frame("A" = c("y", "y", "n", "n"),
                 "B" = c("n", NA, "y", "y"),
                 "C" = c("n", "y", "y", "n"))

mutate(df, across(c(A, B), ~ recode(.x, "n" = "No","y" = "Yes") %>% factor(levels = c("No", "Yes"))))
#>     A    B C
#> 1 Yes   No n
#> 2 Yes <NA> y
#> 3  No  Yes y
#> 4  No  Yes n

您可以通过指定其 levelslabels 参数来使用函数 factor:

library(dplyr)

df <- mutate(df, across(c(A, B), factor, levels=c("n", "y"), labels=c("No", "Yes")))

#     A    B C
# 1 Yes   No n
# 2 Yes <NA> y
# 3  No  Yes y
# 4  No  Yes n

如果你想最终输出为因素,你可以使用来自`forcats.

fct_recode
library(dplyr)
library(forcats)

cols <- c("A", "B")
df <- df %>% mutate(across(all_of(cols), fct_recode, "No" = "n", "Yes" = "y"))
df

#    A    B C
#1 Yes   No n
#2 Yes <NA> y
#3  No  Yes y
#4  No  Yes n

str(df)

#'data.frame':  4 obs. of  3 variables:
# $ A: Factor w/ 2 levels "No","Yes": 2 2 1 1
# $ B: Factor w/ 2 levels "No","Yes": 1 NA 2 2
# $ C: chr  "n" "y" "y" "n"

基础 R 解决方案:

# Function performing a mapping replacement:
# replaceMultipleValues => function() 
replaceMultipleValues <- function(df, mapFrom, mapTo){
  valueMap <- setNames(mapTo, mapFrom)
  res <- data.frame(
    matrix(
      valueMap[unlist(df)], 
      nrow = nrow(df),
      ncol = ncol(df),
      dimnames = dimnames(df)
    )
  )
  return(res)
}

# Application of the function: 
# data.frame => stdout(console)
replaceMultipleValues(
  df, 
  c("y", "n"), 
  c("yes", "no")
)

我们可以使用str_replace_all

library(stringr)
library(dplyr)
df %>%
    mutate(across(A:B, ~ str_replace_all(., setNames( c('No', 'Yes'), c('n', 'y')))))
    A    B C
1 Yes   No n
2 Yes <NA> y
3  No  Yes y
4  No  Yes n