首页 文章

R - 在循环中创建DF(tibbles) . 如何在里面重命名它们和列,包含日期? (我用eval(..)来做,但是有更好的解决方案吗?)

提问于
浏览
0

我有一个循环,在每次迭代结束时创建一个tibble, tbl . Loop每次使用不同的日期, 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 和所有列( colAcolB )名称保持不变)

我想要的输出需要以 output - outputdate1outputdate2 等开头 .
其中的列为 colAdate1 ,_ colBdate1colAdate2colBdate2 等 .

目前我正在使用这段代码,但是不易阅读:

eval(parse(text = (
  paste0("output", year(date), months(date), " <- tbl %>% rename(colA", year(date), months(date), " = 'colA', colB", year(date), months(date), " = 'colB')")
)))

它为eval生成此代码(解析(...)以评估:

"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)
谢谢!

1 回答

  • 0

    这避免了 eval 并且更容易阅读:

    ym <- "2017February"
    assign(paste0("output", ym), setNames(tbl, paste0(names(tbl), ym)))
    

    部分重命名

    如果您只想用字符向量 new 中的相应名称替换字符向量 old 中的名称,请使用以下命令:

    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)))
    

相关问题