通过遍历R中的数据帧列表来创建数据帧

时间:2018-07-03 13:35:49

标签: r loops dataframe

我有一个大型数据集,该数据集被组织为1044个数据帧的列表。每个数据帧都是一个配置文件,在不同的站点和时间保存相同的数据。我试图创建一个保存函数fitsObs输出的数据框,但是我当前的代码仅通过一个数据框。有什么想法吗?

    i=1
start=1
for(i in 1:1044){
  station1 <- surveyCTD$stations[[i]]
  df1 <- surveyCTD$data[[i]]
  date1 <- surveyCTD$dates[[i]]

  fitObs <- fitTp2(-df1$depth, df1$temp)

  if(start==1){
    start=0
    dfout <- data.frame(
      date=date1
      ,station=station1
    )
    names(fitObs) <- paste0(names(fitObs),"o")
    dfout<-cbind(dfout, df1$temp, df1$depth)
    dfout <- cbind(dfout, fitObs)

  }
}

3 个答案:

答案 0 :(得分:0)

乍一看,我将尝试两种方法对其进行调试。首先打印出DF的头部以了解循环的行为,然后检查变量dfout的范围,看起来该变量在循环中是本地的。

此外,循环外的i变量不会更改循环中的任何内容。

答案 1 :(得分:0)

关于您的要求,我创造了一个最好的猜测例子。我还假定您可以调整此一般示例中的概念以适合您自己的问题。如果将来提供清单示例会更容易。

首先,我们创建一些可重复的数据

a <- c(10,20,30,40)
b <- c(5,10,15,20)
c <- c(20,25,30,35)
df1 <- data.frame(x=a+1,y=b+1,z=c+1)
df2 <- data.frame(x=a,y=b,z=c)
ls1 <- list(df1,df2)

看起来像这样

print(ls1)
[[1]]
   x  y  z
1 11  6 21
2 21 11 26
3 31 16 31
4 41 21 36

[[2]]
   x  y  z
1 10  5 20
2 20 10 25
3 30 15 30
4 40 20 35

因此,我们现在在一个列表中有两个数据框。然后,下面的代码应该可以遍历列表的每个数据框中的列,并将mean()函数应用于列中的数据。您可以通过选择“ 1”而不是“ 2”将其更改为行。

df <- do.call("rbind", lapply(ls1, function(x) apply(x,2,mean)))
as.data.frame(df)
print(df)
   x   y   z
1 26 13.5 28.5
2 25 12.5 27.5

您应该能够用为数据编写的任何函数替换mean()。让我知道是否有帮助。

答案 2 :(得分:0)

考虑构建一个通用函数,以Map(包装到mapply apply 系列的 m 多元素逐元素迭代器成员{{ )来建立数据帧列表,每个数据帧都带有您的 fitObs 输出。并将所有等长的对象传递到data.frame()构造函数中。

然后在循环之外,为所有1,044个较小数据帧的最终单个附加数据帧运行do.call(假定每个数据帧保持相同的列数)

# GENERALIZED FUNCTION
add_fit_obs <- function(dt, st, df) {

   fitObs <- fitTp2(-df$depth, df$temp)
   names(fitObs) <- paste0(names(fitObs),"o")

   tmp <- data.frame(
       date = dt,
       station = st,
       depth = df1$depth,
       temp = df1$temp,
       fitObs      
    )

   return(tmp)
}

# LIST OF DATA FRAMES
df_list <- Map(add_fit_obs, surveyCTD$stations, surveyCTD$dates, surveyCTD$data) 
# EQUIVALENTLY:
# df_list <- mapply(add_fit_obs, surveyCTD$stations, surveyCTD$dates, surveyCTD$data, SIMPLIFY=FALSE)

# SINGLE DATAFRAME
master_df <- do.call(rbind, df_list)