首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何动态构建字符串并将其传递给R中dplyr的mutate()函数?

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

Stack Overflow用户
提问于 2020-01-22 12:57:47
回答 2查看 468关注 0票数 2

我以前问过一个类似的问题(链接)。给出的答案很好。然而,事实证明,它并不完全适用于我的用例。

请考虑以下最低限度的工作实例:

代码语言:javascript
运行
复制
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

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

代码语言:javascript
运行
复制
n_par <- 4
str_c('Q', 1:n_par, ' = ', 1:n_par, collapse = ', ')

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

有人能帮忙吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-22 20:11:46

生成和计算字符串

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

代码语言:javascript
运行
复制
> eval(parse(text="print('hello world')"))

#> [1] "hello world"

但是,在dbplyr翻译中,这可能不太好。如果你设法让这种方法奏效,最好能把它作为一个答案发布出来。

使用循环

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

代码语言:javascript
运行
复制
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)

!!sym()必须告诉dplyr,您希望将文本参数作为变量处理。懒惰的评估可以给你奇怪的结果,没有它。需要进行:=分配,因为需要对LHS进行评估。

这种方法大致相当于每个变量的一个可变语句(例如下面的例子),但是dbplyr转换可能不像在一个变体语句中那样优雅。

代码语言:javascript
运行
复制
db <- tbl(con, "mtcars") %>%
    select(carb) %>%
    distinct(carb) %>%
    arrange(carb) %>%
    mutate(Q1 = 1) %>%
    mutate(Q2 = 2) %>%
    ...
    mutate(Qn = n) %>%
    collect()
票数 2
EN

Stack Overflow用户

发布于 2020-02-17 15:45:49

我最近读到了更多关于这个主题的文章,我发现下面的代码工作得很好,因此dbplyr编写了一个更干净的SQL代码。

代码语言:javascript
运行
复制
# Libraries

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

# Example database

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

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

# Parameter for number of variables to be created

n <- 4 

# Variable list

var <- list() 
for(i in 1:n){
    j <- paste0("Q", i) 
    var[[j]] <- i
} 

# Query/computation

db <- tbl(con, "mtcars") %>% 
    select(carb) %>% 
    distinct(carb) %>% 
    arrange(carb) %>% 
    mutate(!!! var) %>% 
    show_query() %>% 
    collect()

诀窍是构建一个具有正确名称的列表,并使用!!!将其放入!!!函数中。此外,我读到应该避免解析和计算字符串,所以我切换到列表。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59860305

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档