r - 如何使用 dplyr 在 R 中的数据库上动态创建新变量/列?
问题描述
我是 Stackoverflow 的新手,对 R 也很陌生。非常感谢您的帮助。
我正在使用dplyr
'smutate()
函数基于一个初始列创建一组新列。对于要创建的先验已知数量的列,一切正常。
但是,在我的应用程序中,要创建的新列的数量是未知的(或者在运行代码之前确定为输入参数)。
为了说明,请考虑以下最小的工作示例:
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 的函数 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
在数据库的情况下,collect
在添加列之前执行
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
或者,如果我们想在collect
ing 之前这样做,另一种选择是传递一个表达式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
推荐阅读
- javascript - 问题:如何获取数组索引id?在 Vuejs 中
- user-interface - 在 Firefox 的 (v71) 开发人员工具中/从并排排列或分离 Inspector 或/和(Web)控制台
- google-sheets - 如何在谷歌表格的arrayformula中加入年份和星期数
- python - pandas根据同一个ID填空值
- azure - Pdftron Sdk 在 azure Web 应用程序服务中抛出错误?
- android-studio - Android studio 3.5.1(SDK 29.0.3) 导致损坏的 avd root
- xamarin.forms - 有没有办法在桌面上禁用 Xamarin Forms SwipeGestureRecognizer?
- machine-learning - 为什么我收到 ValueError?
- html - 轮播内的卡片垂直显示而不是水平显示
- excel - 已定义和设置变量时 VBA 中的错误 91