2016-03-17 53 views
1

我正在编程一个带n层的盒子模型。我想为我在盒子模型中定义的每个图层生成一个数据框,并在每个数据框的每一列中执行计算。我已经初始化使用此代码数据帧:生成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(计算)载体命名为每列我需要在每个层中的数据帧执行特定的计算。我想要将生成的图层数据框附加到列表中,我可以循环使用或使用apply函数,然后使用其变量名中的数字通过数据框为每列写OR函数/方程。我试图追加数据帧,因为他们产生的空列表“layer_tabs”返回的错误:

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

尝试阅读帮助页面,'append'以确定是否该函数的作用,你需要什么,以及如何如果是这样使用它。 – Frank

+0

错误消息是因为'append'中没有名为'nam'的参数。另外,您的'layer_tabs'对象没有更新,因为每次修改结果时都必须指定结果'layer_tabs < - append(layer_tabs,nam')。 – nrussell

+1

你不应该使用'assign'或者'append'。只要在代码中看到这两个函数,我就绝对相信有一个更可读和更高效的解决方案(针对您的实际问题)。 – Roland

回答

0

这听起来像你想创建名称“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 
+0

但是,当然没有很好的理由来创建空的data.frames。接下来,他们将通过在循环中追加行来填充它们。 – Roland

+0

@Roland yup,尽管没有更广泛的用户代码视图,恐怕我们没有太多的工作可以帮助。 – josliber

+0

'rep(list(DF),3)'是另一种选择(替代'replicate(3,DF,simplify = FALSE)') – Frank

0

我完成了我的使用下面的代码尝试:

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] 
    } 
    } 
} 

这可能不是实现我的目标的最有效的方式,但它的确有用。谢谢您的意见。我尝试了setNames方法,但我无法弄清楚如何将这些数据帧存储在列表中,而无需真正知道有多少层。这篇文章最让我:

Adding data frames as list elements (using for loop)