1

更新:我的 NOAA GHCN-Daily 气象站数据功能已被清理并合并到rnoaa包中,可在 CRAN 或此处获取: https ://github.com/ropensci/rnoaa

我正在设计一个 R 函数来计算由多个数据帧组成的数据集的统计数据。简而言之,我想根据包含名称的参考数据框按类提取数据框。然后,我想将统计函数应用于每个给定日期列出的指标的值。实际上,我想调用并覆盖数据框列表,以计算每个唯一日期和度量值的值向量上的函数,其中值不是 NA。

使用“by”函数,基于类变量将数据帧从文件中迭代地读入工作区。导入给定类的文件后,我想 rbind() 该类的数据框和一个年份范围内的每个用户定义的指标。然后,我想将用户提供的统计函数串联应用于与年、月和日的给定值相对应的类中的每个指标(即,7 月 1 日的平均 [函数] 低温 [类], 1990 [日期] 报告给定区域 [类] 内的所有位置 [数据框]。我希望最终结果是新的数据框,其中包含区域内每个日期的值以及应用的每个指标和统计函数的年份范围。我非常接近使用 aggregate() 函数得到这个结果,但我无法从聚合函数中获得合理的结果,该函数目前为除平均温度以外的大多数函数输出 NA 和 NaN。任何建议将不胜感激!到目前为止,这是我的代码:

# Example parameters
w <- c("mean","sd","scale")             # Statistical functions to apply
x <- "C:/Data/"                         # Folder location of CSV files
y <- c("MaxTemp","AvgTemp","MinTemp")   # Metrics to subset the data
z <- c(1970:2000)                       # Year range to subset the data

 CSVstnClass  <- data.frame(CSVstations,CSVclasses)

  by(CSVstnClass, CSVstnClass[,2], function(a){                        # Station list by class
  suppressWarnings(assign(paste(a[,2]),paste(a[,1]),envir=.GlobalEnv))
    apply(a, 1, function(b){                                           # Data frame list, row-wise
      classData   <- data.frame()
      sapply(y, function(d){                                           # Element list
        CSV_DF    <- read.csv(paste(x,b[2],"/",b[1],".csv",sep=""))    # Read in CSV files as data frames
        CSV_DF1   <- CSV_DF[!is.na("Value")]
        CSV_DF2   <- CSV_DF1[which(CSV_DF1$Year %in% z & CSV_DF1$Element == d),]
        assign(paste(b[2],"_",d,sep=""),CSV_DF2,envir=.GlobalEnv)

        if(nrow(CSV_DF2) > 0){                                         # Remove empty data frames
          classData <<- rbind(classData,CSV_DF2)                       # Bind all data frames by row for a class and element
          assign(paste(b[2],"_",d,"_bound",sep=""),classData,envir=.GlobalEnv)

          sapply(w, function(g){                                       # Function list
                                                                       # Aggregate results of bound data frame for each unique date
            dataFunc <- aggregate(Value~Year+Month+Day+Element,data=classData,FUN=g,na.action=na.pass)
            assign(paste(b[2],"_",d,"_",g,sep=""),dataFunc,envir=.GlobalEnv)
            })
        }
        })
      })
    })

我想我已经很接近了,但我不确定 rbind() 是否正常执行,也不确定为什么 aggregate() 函数会为这么多指标输出 NA 和 NaN 。我担心数据框没有绑定在一起,或者某些统计函数没有很好地处理缺失值。提前感谢您提供的任何建议。

干杯,

亚当

4

1 回答 1

2

您已经以一种很难调试的方式解决了这个问题。我建议您切换一些东西,这样您就可以更轻松地检查每个步骤。(使用信息变量名也有帮助!)代码不太可能按原样工作,但迭代工作应该更容易,在继续下一步之前检查每个步骤是否成功。

paths <- dir("C:/Data/", pattern = "\\.csv$")

# Read in CSV files as data frames
raw <- lapply(paths, read.csv, str)

# Extract needed rows
filter_metrics <- c("MaxTemp", "AvgTemp", "MinTemp")
filter_years <- 1970:2000
filtered <- lapply(raw, subset, 
  !is.na(Value) & Year %in% filter_years & Element %in% filter_metrics)

# Drop any empty data frames
rows <- vapply(filtered, nrow, integer(1))
filtered <- filtered[rows > 0]

# Compute aggregates
my_aggregate <- function(df, fun) {
  aggregate(Value ~ Year + Month + Day + Element, data = df, FUN = fun, 
    na.action = na.pass)
}    
means <- lapply(filtered, my_aggregate, mean)
sds <- lapply(filtered, my_aggregate, sd)
scales <- lapply(filtered, my_aggregate, scale)
于 2013-08-01T12:40:27.847 回答