【问题标题】:A set of functions over multiple data frames and merge the outputs in R多个数据帧上的一组函数并合并 R 中的输出
【发布时间】:2020-06-07 13:43:32
【问题描述】:

我有多个数据帧(在 130 个观察点处移动不同持续时间的温度),并希望通过将以下代码应用于每个数据帧来生成所有数据的月平均值 - 然后将结果放入一个数据帧中。我一直在尝试使用 for 循环来做到这一点,但没有得到任何结果。我对 R 比较陌生,如果有人能帮助我解决这个问题,我真的很感激。

这是一个数据框的一瞥:

head(maxT2016[,1:5])

      X       X0       X1       X2       X3
1 20160101 26.08987 26.08987 26.08987 26.08987
2 20160102 25.58242 25.58242 25.58242 25.58242
3 20160103 25.44290 25.44290 25.44290 25.44290
4 20160104 26.88043 26.88043 26.88043 26.88043
5 20160105 26.60278 26.60278 26.60278 26.60278
6 20160106 24.87676 24.87676 24.87676 24.87676

str(maxT2016)
'data.frame':   274 obs. of  132 variables:
$ X   : int  20160101 20160102 20160103 20160104 20160105 20160106 20160107 20160108 20160109 20160110 ...

$ X0  : num  26.1 25.6 25.4 26.9 26.6 ...
$ X1  : num  26.1 25.6 25.4 26.9 26.6 ...
$ X2  : num  26.1 25.6 25.4 26.9 26.6 ...
$ X3  : num  26.1 25.6 25.4 26.9 26.6 ...

这是我用于单个数据框的代码:

library(dplyr)
library(lubridate)
library(tidyverse)

maxT10$X <- as.Date(as.character(maxTsma10$X), format="%Y%m%d") 

monthlyAvr <- maxT10 %>%
  group_by(month=floor_date(date, "month")) %>%
  summarise(across(X0:X130, mean, na.rm=TRUE)) %>%
  slice_tail(n=6) %>%
  select(-month)

monthlyAvr2 <- as.data.frame(t(montlyAvr))
colnames(monthlyAvr2) <- c("meanT_Apr", "meanT_May", "meanT_Jun", "meanT_Jul", "meanT_Aug", 
"meanT_Sep")

本质上,我想将所有所有数据帧放入一个列表中并通过所有数据帧运行该函数,然后将这些输出排序到一个数据帧中。我遇到了 lapply 函数作为替代方案,但对 for-loop 感觉更舒服。

d = list(maxT10, maxT20, maxT30, maxT60 ... ...)

for (i in 1:lengh(d)){

}

MonthlyAvrT <- cbind(maxT10, maxT20, maxT30, maxT60... ... ) 

【问题讨论】:

    标签: r for-loop lapply


    【解决方案1】:

    罗勒。欢迎使用 StackOverflow。

    当我第一次说使用 R 时,我对 lapply 持谨慎态度,但你应该坚持下去。它几乎总是比使用 for 循环更有效。在您的特定情况下,您可以将您的各个数据框放在 list 中,并将您在每个数据框上运行的代码放入一个函数 myFunc 中,例如,它将您要处理的数据框作为其参数。

    那你可以简单地说

    allData <- bind_rows(lapply(1:length(dataFrameList), function(x) myFunc(dataFrameList[[x]])))
    

    顺便说一句,你的列名让我觉得你的数据还不是tidy。我建议你在做很多其他事情之前花一点时间来制作它。从长远来看,它将为您节省大量的精力。

    【讨论】:

    • 非常好的建议。在您的示例中,x 是列表中 data.frame 的索引,@Basil 您也可以直接将 lapply 与 data.frames 列表一起使用并在 data.frame 上执行您的功能:lapply(dataFrameList, function(x) myFunc(x))
    • 谢谢@Limey 和@starja!整洁的数据文章已经帮助我意识到我必须回到开始处理原始数据的几个步骤。之后我将探索“lapply”。
    • 不客气,巴兹尔。这只会退后一小步,但我向您保证从长远来看这是值得的。恕我直言,在 SO 上发布的绝大多数“我有一个困难的数据处理步骤”问题都是由于在工作流程的早期选择了不适当的数据格式。
    • @Limey,你是对的。我一直回到我开始使用的原始数据框。确实很乱。我遵循整理数据的原则。然后我想采取的所有后续步骤突然变得容易 - 甚至在没有 lapply 的情况下也可以管理。非常感谢!
    • 我很高兴能提供帮助。 :)
    【解决方案2】:

    伪代码中的逻辑是:

    for each data.frame in list
        apply a function
        save the results
    

    data_set 列表的每个data.frame 上应用my_function

    my_function <- function(my_df) {
    
      my_df <- as.data.frame(my_df)
      out <- apply(my_df, 2, mean)  # compute mean on dimension 2 (columns)
      return(out)
    
    }
    
    # 100 data.frames
    data_set <- replicate(100, data.frame(X=runif(6, 20160101, 20160131), X0=rnorm(6, 25)))
    
    > dim(data_set) 
    [1]   2 100
    
    results <- apply(data_set, 2, my_function)  # Apply my_function on dimension 2
    
    # Output for first 5 data.frames
    
    > results[, 1:5]                                                                                                                                                                          
               [,1]         [,2]         [,3]         [,4]         [,5]                                                                  
    
    X  2.016012e+07 2.016011e+07 2.016011e+07 2.016012e+07 2.016011e+07                                                                                                                       
    X0 2.533888e+01 2.495086e+01 2.523087e+01 2.491822e+01 2.482142e+01
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-15
    • 1970-01-01
    • 2020-07-28
    • 2019-03-29
    • 1970-01-01
    • 2013-01-03
    • 2020-02-18
    • 2014-04-23
    相关资源
    最近更新 更多