R - 在循环中创建 DF(tibbles)。如何重命名它们和里面的列,包括日期? (我用 eval(..) 来做,但是有更好的解决方案吗?)
R - Creating DFs (tibbles) in a loop. How to rename them and columns inside, to include date? (I do it with eval(..), but is there a better solution?)
我有一个循环,它在每次迭代结束时创建一个小标题,tbl。每次循环使用不同的日期,date.
假设:
tbl <- tibble(colA=1:5,colB=5:10)
date <- as.Date("2017-02-28")
> tbl
# A tibble: 5 x 2
colA colB
<int> <int>
1 1 5
2 2 6
3 3 7
4 4 8
5 5 9
(内容在每个循环中都在变化,但是 tbl、date 和所有列 (colA, colB) 名称保持不变)
我想要的输出需要以 output - outputdate1, outputdate2 等开头.
其中的列为 colAdate1、colBdate1 和 colAdate2、colBdate2 等等。
目前我正在使用这段代码,它可以工作,但不容易阅读:
eval(parse(text = (
paste0("output", year(date), months(date), " <- tbl %>% rename(colA", year(date), months(date), " = 'colA', colB", year(date), months(date), " = 'colB')")
)))
它为 eval(parse(...) 生成此代码以评估:
"output2017February <- tbl %>% rename(colA2017February = 'colA', colB2017February = 'colB')"
这给了我想要的输出:
> output2017February
# A tibble: 5 x 2
colA2017February colB2017February
<int> <int>
1 1 5
2 2 6
3 3 7
4 4 8
5 5 9
有更好的方法吗? (最好使用 dplyr)
谢谢!
这避免了eval
并且更容易阅读:
ym <- "2017February"
assign(paste0("output", ym), setNames(tbl, paste0(names(tbl), ym)))
部分重命名
如果您只想将字符向量 old
中的名称替换为字符向量 new
中的相应名称,则使用以下内容:
assign(paste0("output", ym),
setNames(tbl, replace(names(tbl), match(old, names(tbl)), new)))
变化
您可以考虑将您的数据框放在一个列表中,而不是在您的工作区中放置一堆松散的对象:
L <- list()
L[[paste0("output", ym)]] <- setNames(tbl, paste0(names(tbl), ym))
.GlobalEnv
也可以用来代替 L
(省略 L <- list()
行)如果你想要这种风格但仍然将对象单独放在全局环境中。
dplyr
这里使用的是 dplyr 和 rlang,但确实增加了复杂性:
library(dplyr)
library(rlang)
.GlobalEnv[[paste0("output", ym)]] <- tbl %>%
rename(!!!setNames(names(tbl), paste0(names(tbl), ym)))
我有一个循环,它在每次迭代结束时创建一个小标题,tbl。每次循环使用不同的日期,date.
假设:
tbl <- tibble(colA=1:5,colB=5:10)
date <- as.Date("2017-02-28")
> tbl
# A tibble: 5 x 2
colA colB
<int> <int>
1 1 5
2 2 6
3 3 7
4 4 8
5 5 9
(内容在每个循环中都在变化,但是 tbl、date 和所有列 (colA, colB) 名称保持不变)
我想要的输出需要以 output - outputdate1, outputdate2 等开头.
其中的列为 colAdate1、colBdate1 和 colAdate2、colBdate2 等等。
目前我正在使用这段代码,它可以工作,但不容易阅读:
eval(parse(text = (
paste0("output", year(date), months(date), " <- tbl %>% rename(colA", year(date), months(date), " = 'colA', colB", year(date), months(date), " = 'colB')")
)))
它为 eval(parse(...) 生成此代码以评估:
"output2017February <- tbl %>% rename(colA2017February = 'colA', colB2017February = 'colB')"
这给了我想要的输出:
> output2017February
# A tibble: 5 x 2
colA2017February colB2017February
<int> <int>
1 1 5
2 2 6
3 3 7
4 4 8
5 5 9
有更好的方法吗? (最好使用 dplyr)
谢谢!
这避免了eval
并且更容易阅读:
ym <- "2017February"
assign(paste0("output", ym), setNames(tbl, paste0(names(tbl), ym)))
部分重命名
如果您只想将字符向量 old
中的名称替换为字符向量 new
中的相应名称,则使用以下内容:
assign(paste0("output", ym),
setNames(tbl, replace(names(tbl), match(old, names(tbl)), new)))
变化
您可以考虑将您的数据框放在一个列表中,而不是在您的工作区中放置一堆松散的对象:
L <- list()
L[[paste0("output", ym)]] <- setNames(tbl, paste0(names(tbl), ym))
.GlobalEnv
也可以用来代替 L
(省略 L <- list()
行)如果你想要这种风格但仍然将对象单独放在全局环境中。
dplyr
这里使用的是 dplyr 和 rlang,但确实增加了复杂性:
library(dplyr)
library(rlang)
.GlobalEnv[[paste0("output", ym)]] <- tbl %>%
rename(!!!setNames(names(tbl), paste0(names(tbl), ym)))