如何动态构建字符串并将其传递给 R 中 dplyr 的 mutate() 函数?

2024-04-21

我之前也问过类似的问题(Link https://stackoverflow.com/questions/59440107/how-can-i-dynamically-create-new-variables-columns-on-databases-in-r-using-dplyr)。给出的答案效果很好。然而,事实证明,它并不完全适用于我的用例。

请考虑以下最小工作示例:

library(RSQLite)
library(dplyr)
library(dbplyr)
library(DBI)
library(stringr)

con <- DBI::dbConnect(RSQLite::SQLite(), path = ":memory:")

copy_to(con, mtcars, "mtcars", temporary = FALSE)

db <- tbl(con, "mtcars") %>%
    select(carb) %>%
    distinct(carb) %>%
    arrange(carb) %>% 
    mutate(Q1=1, Q2=2, Q3=3, Q4=4) %>% 
    collect()

我对动态构建字符串感兴趣Q1=1, Q2=2, Q3=3, Q4=4这样它就可以是Q1=1, Q2=2, ..., Qn = n.

我的一个想法是像这样构建字符串:

n_par <- 4
str_c('Q', 1:n_par, ' = ', 1:n_par, collapse = ', ')

这样 n_par 可以是任何正数。然而,由于 dplyr 的非标准评估,我无法让它像那样工作。然而,这正是我所需要的。

有人可以帮忙吗?


生成并评估字符串

Q1 = 1, Q2 = 2, Q3 = 3, Q4 = 4不是一个字符串,就像"Q1 = 1, Q2 = 2, Q3 = 3, Q4 = 4"是一个字符串。有一些 R 函数会接受字符串对象并将其作为代码进行计算。例如:

> eval(parse(text="print('hello world')"))

#> [1] "hello world"

然而,这在内部可能效果不佳dbplyr翻译。如果您设法让类似的方法发挥作用,那么很高兴看到它作为答案发布。

使用循环

另一种方法是使用循环,而不是将其作为单个字符串执行:

db <- tbl(con, "mtcars") %>%
    select(carb) %>%
    distinct(carb) %>%
    arrange(carb)

for(i in 1:n){
    var = paste0("Q",i)
    db <- db %>%
        mutate(!!sym(var) := i)
}

db <- collect(db)

The !!sym()需要告诉dplyr您希望将文本参数视为变量。如果没有它,惰性求值会给你带来奇怪的结果。这:=需要分配,因为需要评估 LHS。

这种方法大致相当于每个变量一个 mutate 语句(下面的示例),但是dbplyr翻译可能看起来不如在单个 mutate 语句中完成所有操作那么优雅。

db <- tbl(con, "mtcars") %>%
    select(carb) %>%
    distinct(carb) %>%
    arrange(carb) %>%
    mutate(Q1 = 1) %>%
    mutate(Q2 = 2) %>%
    ...
    mutate(Qn = n) %>%
    collect()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何动态构建字符串并将其传递给 R 中 dplyr 的 mutate() 函数? 的相关文章

随机推荐