r - 如何使用 dplyr 在 R 中的数据库上动态创建新变量/列?

标签 r dplyr

我是 Stackoverflow 的新手,也是 R 的新手。我非常感谢您的帮助。

我正在使用 dplyrmutate() 函数基于一个初始列创建一组新列。对于要创建的先验已知数量的列,一切正常。

但是,在我的应用程序中,要创建的新列的数量是未知的(或者更确切地说,在运行代码之前确定为输入参数)。

为了便于说明,请考虑以下最小工作示例:

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

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(carb1 = carb + 1) %>%
    mutate(carb2 = carb + 2) %>%
    mutate(carb3 = carb + 3) %>%
    show_query() %>%
    collect()

在此示例中,我创建了三个新变量。但是,我希望程序能够处理动态数量的变量(例如,五个或十个新变量)。我还想在 collect() 之前完成所有计算,因为我想尽可能晚地将数据复制到内存中。

我的现实生活应用程序的一些背景:我想使用 DB2's function ADD_MONTHS() 。因此,我需要 dplyr/dbplyr 将该函数直接刷新到 SQL 命令中。因此,我需要一个实际上不使用数据框逻辑的解决方案 - 我需要该解决方案位于 dplyr 中。

从不同的角度来看:在 SAS 中,我会使用宏处理器来动态构建 proc sql 语句。 R 中有等效的吗?

最佳答案

我们可以使用 map

library(dplyr)
library(purrr)
library(stringr)
map_dfc(1:3, ~ df %>%
                  transmute(!! str_c('x', .x) := x + .x)) %>%
    bind_cols(df, .)
#  x x1 x2 x3
#1 1  2  3  4
#2 2  3  4  5
#3 3  4  5  6

如果是数据库,请在添加列之前进行收集

dat <- tbl(con, "mtcars") %>%
        select(carb) %>%
        distinct(carb) %>%
        arrange(carb) %>%
        collect()
map_dfc(dat$carb, ~ dat %>%
                      transmute(!! str_c('carb', .x) := carb + .x)) %>%
    bind_cols(dat, .)
# A tibble: 6 x 7
#   carb carb1 carb2 carb3 carb4 carb6 carb8
#  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1     1     2     3     4     5     7     9
#2     2     3     4     5     6     8    10
#3     3     4     5     6     7     9    11
#4     4     5     6     7     8    10    12
#5     6     7     8     9    10    12    14
#6     8     9    10    11    12    14    16

如果我们想在收集之前执行此操作,另一种选择是在 mutate 中传递表达式

tbl(con, "mtcars") %>%
   select(carb) %>%
   distinct(carb) %>%
   arrange(carb) %>%
   mutate(!!! rlang::parse_exprs(str_c('carb', 1:3, sep="+", collapse=";"))) %>%
   rename_at(-1, ~ str_c('carb', 1:3)) %>%
   show_query() %>%
   collect()
#<SQL>
#SELECT `carb`, `carb` + 1.0 AS `carb1`, `carb` + 2.0 AS `carb2`, `carb` + 3.0 AS #`carb3`
#FROM (SELECT *
#FROM (SELECT DISTINCT *
#FROM (SELECT `carb`
#FROM `mtcars`))
#ORDER BY `carb`)
# A tibble: 6 x 4
#   carb carb1 carb2 carb3
#  <dbl> <dbl> <dbl> <dbl>
#1     1     2     3     4
#2     2     3     4     5
#3     3     4     5     6
#4     4     5     6     7
#5     6     7     8     9
#6     8     9    10    11

关于r - 如何使用 dplyr 在 R 中的数据库上动态创建新变量/列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59440107/

相关文章:

r - 从 R 调用 Prolog

r - 用第一个值总结

r - 检查 R 列中是否存在值向量,然后返回单个 True 值

r - 如何合并表并匹配具有多个因素的列的名称

r - 以编程方式使用带参数的 dplyr::case_when

r - 在基组之间切换时是否可以在多个图例之间切换?

r - 将虚拟矩阵融化为一列

r - 提取部分字符串值,创建新的列名,并使数据框变宽

r - 如何展平非原子函数结果,以便可以将其分配为dplyr突变步骤的一部分?

r - 如何将列名传递到使用 dplyr 的自定义函数中?