首页 > 解决方案 > 仅当变量存在时才执行变异功能

问题描述

我有一个函数可以将特定函数应用于数据框中的多个列。这些函数中的每一个都是唯一的,并且只能应用于该列。

convert_columns <- function(df) {
    df %>% mutate(
        a = convert_a(a),
        b = convert_b(b),
        c = convert_c(c),
        d = convert_d(d),
        e = convert_e(e)
        )
}

但是,用户可能会输入一个只有这些列的子集的数据框(例如,只有ab和列和.cmutateabcde

我努力了

convert_columns <- function(df) {
    df %>% mutate(across(any of(),
        a = convert_a(a),
        b = convert_b(b),
        c = convert_c(c),
        d = convert_d(d),
        e = convert_e(e)
        ))
}

convert_columns <- function(df) {
    df %>% mutate(across(any of(
        a = convert_a(a),
        b = convert_b(b),
        c = convert_c(c),
        d = convert_d(d),
        e = convert_e(e)
        )))
}

这些不起作用。语法中是否有一种简单的方法tidyverse来完成我想要做的事情?在我的实际用例中,我有大约 150 列将发生变异。

标签: rdplyrtidyverse

解决方案


由于函数对于每个变量都是唯一的,并且如果其中一列失败,您希望返回剩余值,因此无法真正提出比tryCatch在单个列上使用更好的解决方案。

library(dplyr)

convert_columns <- function(df) {
  df %>% 
    mutate(
    a = tryCatch(convert_a(a),error = function(z) return(NA)),
    b = tryCatch(convert_b(b),error = function(z) return(NA)),
    c = tryCatch(convert_c(c),error = function(z) return(NA)),
    #...
    #...
    )
}

这可以使用以下mtcars示例进行测试:

这有效 -

mtcars %>%
  mutate(a = n_distinct(cyl), 
         b = mean(mpg), 
         c = sd(am))

现在,如果我们删除其中一列,上述失败:

mtcars %>%
  select(-am) %>%
  mutate(a = n_distinct(cyl), 
         b = mean(mpg), 
         c = sd(am))

错误:mutate()输入有问题c。x 不能将类型 'closure' 强制转换为类型为 'double' 的向量 ℹ 输入csd(am).

现在使用tryCatch

mtcars %>%
  select(-am) %>%
  mutate(a = tryCatch(n_distinct(cyl), error = function(e) return(NA)), 
         b = tryCatch(mean(mpg), error = function(e) return(NA)), 
         c = tryCatch(sd(am), error = function(e) return(NA)))

#   mpg cyl disp  hp drat  wt qsec vs gear carb a  b  c
#1   21   6  160 110  3.9 2.6   16  0    4    4 3 20 NA
#2   21   6  160 110  3.9 2.9   17  0    4    4 3 20 NA
#3   23   4  108  93  3.9 2.3   19  1    4    1 3 20 NA
#4   21   6  258 110  3.1 3.2   19  1    3    1 3 20 NA
#....

推荐阅读