【问题标题】:Trying to repeat the same code for multiple dataframes尝试为多个数据帧重复相同的代码
【发布时间】:2019-03-27 01:30:06
【问题描述】:

我有以下代码,它接受一个名为 dft1 的数据帧,然后生成一个名为 dfb1 的结果数据帧。我想对多个输入数据帧(如 dft1、dft2)重复相同的代码,所有这些数据帧都由一个数字索引到最后,然后使用相同的模式存储结果,即 dfb1、dfb2、...。 我尝试了许多方法,例如使用 dapply 或 for 循环,但鉴于内部代码的性质,我无法获得预期的结果。


#define the function for rolling

window <- 24
rolling_lm <- 
  rollify(.f = function(R_excess, MKT_RF, SMB, HML) {
    lm(R_excess ~ MKT_RF + SMB + HML)
  }, window = window, unlist = FALSE)

#rolling over the variable 

dfb1 <-
  dft1 %>% 
  mutate(rolling_ff = 
           rolling_lm(R_excess, 
                      MKT_RF, 
                      SMB, 
                      HML)) %>% 
  mutate(tidied = map(rolling_ff, 
                      tidy, 
                      conf.int = T)) %>% 
  unnest(tidied) %>% 
  slice(-1:-23) %>% 
  select(date, term, estimate, conf.low, conf.high) %>% 
  filter(term != "(Intercept)") %>% 
  rename(beta = estimate, factor = term) %>% 
  group_by(factor)

【问题讨论】:

标签: r loops lapply dplyr repeat


【解决方案1】:

在函数中添加要应用到每个数据帧的命令

apply_fun <- function(df) {
   df %>% 
    mutate(rolling_ff = 
         rolling_lm(R_excess, 
                    MKT_RF, 
                    SMB, 
                    HML)) %>% 
    mutate(tidied = map(rolling_ff, 
                    tidy, 
                    conf.int = T)) %>% 
    unnest(tidied) %>% 
    slice(-1:-23) %>% 
    select(date, term, estimate, conf.low, conf.high) %>% 
    filter(term != "(Intercept)") %>% 
    rename(beta = estimate, factor = term) %>% 
    group_by(factor)
}

现在将函数应用于每个数据帧并将结果存储在列表中

n <- 10
out <- setNames(lapply(mget(paste0("dft", 1:n)), apply_fun), paste0("dfb", 1:n))

假设您有像dft1dft2 这样的输入数据框...这将输出一个数据框列表,您现在可以通过out[['dfb1']]out[['dfb2']] 等方式访问这些数据框。根据您拥有的 dft 数据帧的数量更改 n 的值。

如果数据已经存在于列表中,我们可以通过这样做来避免mget

setNames(lapply(result, apply_fun), paste0("dfb", 1:n))

【讨论】:

  • 非常感谢您的帮助。当我尝试运行代码时出现错误:mget(paste0("dft"), 1:n) 中的错误:第二个参数必须是一个环境还有一种方法可以做同样的事情,但是当你的数据帧在一个列出例如我有一个名为 result {dft1, dft2, ....} 的列表,我想将我的函数应用于列表并将结果作为数据帧列表 {dfb1, dfb2,...}。
  • @ErwinRhine mget 命令用于将单个数据帧带入列表本身,因此如果您已经拥有它们,那就太好了。你可以做setNames(lapply(result, apply_fun), paste0("dfb", 1:n))。你能试着让我知道它是否有效吗?同样在mget 尝试中,我放错了一个括号,它应该是setNames(lapply(mget(paste0("dft", 1:n)), apply_fun), paste0("dfb", 1:n))
  • 非常感谢这两种方法都有效,我会坚持使用列表,因为它更容易。
猜你喜欢
  • 2022-01-10
  • 1970-01-01
  • 2016-02-28
  • 2012-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-17
  • 1970-01-01
相关资源
最近更新 更多