0

让我们假设以下数据:

df <- data.frame(x = c(1, 2),
                 y = c(3, 4),
                 z = c(5, 6))

让我们进一步假设我有一个包含我想要处理的列名的向量,例如

var_names_1 <- c("test", "x", "y")
var_names_2 <- c("test", "z")

现在我想要做的是改变对象中除第一个元素之外的所有列,df使用. (在这种情况下,我会循环遍历我的两个 var_names 对象)。var_names_...across

所以在第一个循环中我想改变列 x 和 y,在第二个循环中我想改变 z。

for (i in 1:2)
{
  df %>%
    mutate(across(!!sym(paste0("var_names_", i, [-1])), as_factor))
}

但是,我收到此错误消息:

Error: Problem with `mutate()` input `..1`.
x Can't subset columns that don't exist.
x Column `var_names_1` doesn't exist.
i Input `..1` is `across(`var_names_1`, as_factor)`.

我以为我终于了解了一些 tidyeval 事物的用例,但显然我的!!sym方法在这里行不通。有什么建议么?

4

2 回答 2

3

我们可以用any_ofacross

library(dplyr)
df1 <- df %>%
    mutate(across(any_of(c(var_names_1, var_names_2)),  factor))

-输出

str(df1)
#'data.frame':  2 obs. of  3 variables:
# $ x: Factor w/ 2 levels "1","2": 1 2
# $ y: Factor w/ 2 levels "3","4": 1 2
# $ z: Factor w/ 2 levels "5","6": 1 2 

或者如果我们需要传入一个循环,一个选项map将是

map(list(var_names_1, var_names_2),
        ~ {df <- df %>%
                 mutate(across(any_of(.x), factor))
          })      

或使用for循环

for(i in 1:2) {
     df <- df %>%
              mutate(across(any_of(get(str_c("var_names_", i))), factor))
 }
于 2021-02-03T20:53:57.030 回答
1

也许你应该试试eval+str2expression

for (i in 1:2){
  str(df %>%
    mutate(across(eval(str2expression(paste0("var_names_", i,"[-1]"))), as_factor)))
}

这表明

'data.frame':   2 obs. of  3 variables:
 $ x: num  1 2
 $ y: Factor w/ 2 levels "3","4": 1 2
 $ z: num  5 6
'data.frame':   2 obs. of  3 variables:
 $ x: num  1 2
 $ y: num  3 4
 $ z: num  5 6
于 2021-02-03T20:42:47.640 回答