【问题标题】:Generate n data frames and append to list生成 n 个数据帧并追加到列表
【发布时间】:2016-07-03 22:26:35
【问题描述】:

我正在编写一个有 n 层的盒子模型。我想为我在盒子模型中定义的每一层生成一个数据框,并在每个数据框的每一列中执行计算。我已经使用以下代码初始化了数据框:

##Initialize layer energy+water balance dataframes
calcs <- c("Vwin", "Vwout", "Vsin","Vsout","Pistd","Vwnet","Psin","Psout","Vw","Vemax","Sw","Cp","Kt","Qwout","Qtop","Qbot","Qsides","Qnet","Tavg")
layer_tabs<-list()

for(i in 2:(layers-1)){
  nam <- paste("layer_",i,sep = "")
  assign(nam,data.frame(matrix(vector(),t,length(calcs),dimnames = list(c(),calcs))))
  append(layer_tabs, nam=nam)
}

现在,对于在我的 calcs 向量中命名的每一列,我需要在每一层数据帧中执行特定的计算。我想将生成的图层数据帧附加到我可以循环的列表中,或者在其上使用应用函数,然后为每列编写函数/方程,或者使用变量名称中的数字循环遍历数据帧.我尝试将生成的数据框附加到空列表“layer_tabs”返回错误:

Error in append(layer_tabs, nam = nam) : unused argument (nam = nam)

【问题讨论】:

  • 尝试阅读帮助页面,?append,以确定该功能是否满足您的需求,以及如何使用它。
  • 错误信息是因为append中没有名为nam的参数。此外,您的 layer_tabs 对象没有更新,因为您必须在每次修改时分配结果,layer_tabs &lt;- append(layer_tabs, nam)。
  • 您不应该使用assignappend。我绝对确定只要在您的代码中看到这两个函数,就会有一个更具可读性和更有效的解决方案(针对您的实际问题)。

标签: r


【解决方案1】:

听起来您正在尝试创建一个名称为“layer_2”、“layer_3”、... 的列表,其中包含带有来自 calcs 变量的列名的空数据框。您可以使用replicatesetNames 在一行中完成此操作:

setNames(replicate(layers-2, data.frame(matrix(vector(), nrow=0, ncol=length(calcs),
                                               dimnames = list(c(),calcs))),
                   simplify=FALSE),
         paste0("layer_", 2:(layers-1)))
# $layer_2
#  [1] Vwin   Vwout  Vsin   Vsout  Pistd  Vwnet  Psin   Psout  Vw     Vemax  Sw    
# [12] Cp     Kt     Qwout  Qtop   Qbot   Qsides Qnet   Tavg  
# <0 rows> (or 0-length row.names)
# 
# $layer_3
#  [1] Vwin   Vwout  Vsin   Vsout  Pistd  Vwnet  Psin   Psout  Vw     Vemax  Sw    
# [12] Cp     Kt     Qwout  Qtop   Qbot   Qsides Qnet   Tavg  
# <0 rows> (or 0-length row.names)
# 
# $layer_4
#  [1] Vwin   Vwout  Vsin   Vsout  Pistd  Vwnet  Psin   Psout  Vw     Vemax  Sw    
# [12] Cp     Kt     Qwout  Qtop   Qbot   Qsides Qnet   Tavg  
# <0 rows> (or 0-length row.names)

数据:

calcs <- c("Vwin", "Vwout", "Vsin","Vsout","Pistd","Vwnet","Psin","Psout","Vw","Vemax","Sw","Cp","Kt","Qwout","Qtop","Qbot","Qsides","Qnet","Tavg")
layers <- 5

【讨论】:

  • 但是当然没有充分的理由创建空的data.frames。接下来,他们将通过在循环中附加行来填充它们。
  • @Roland 是的,虽然没有更广泛的用户代码视图,但恐怕我们无能为力。
  • rep(list(DF), 3) 是另一种选择(替代replicate(3,DF,simplify=FALSE)
【解决方案2】:

我使用以下代码完成了我正在尝试的事情:

for(i in 2:(layers-1)){
 nam <- paste("layer_",i,sep = "")
 layer_tabs[[nam]]<-assign(nam,data.frame(t,matrix(data=rep(0,times=length(t)*length(calcs)),nrow=length(t),ncol=(length(calcs)),dimnames = list(c(),calcs))))

}

这允许我为未知数量的层创建数据框并将它们存储在一个列表中,我可以使用双 for 循环对每个数据框中的给定变量对应的所有列进行计算,这将允许我循环通过每个数据帧和时间:

for(i in 1:length(layer_tabs)){
  for(j in 1:length(t)){
    if(j==1){
      #assign initial values
      layer_tabs[[i]]$Sw[j] <- physical_inputs$sat[i+1]
    }
  }
}

这可能不是实现我的目标的最有效方式,但它可以解决问题。谢谢你们的cmets。我尝试了 setNames 方法,但我不知道如何在不知道有多少层的情况下将这些数据帧存储在列表中。这篇文章对我帮助最大:

Adding data frames as list elements (using for loop)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-07
    • 2020-02-01
    • 2016-04-29
    • 1970-01-01
    • 1970-01-01
    • 2021-09-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多