【问题标题】:apply function to subsets of dataframe r将函数应用于数据帧 r 的子集
【发布时间】:2020-02-17 18:25:23
【问题描述】:

我正在尝试通过两个变量(“站点”和“年份”)对数据框进行子集化,并将函数 (dismo::biovars) 应用于每个子集。 Biovars 需要每月输入(12 个值)并每年输出 19 个变量。我想存储每个子集的输出并将它们组合起来。

示例数据:

data1<-data.frame(Meteostation=c(rep("OBERHOF",12),rep("SOELL",12)),
              Year=c(rep(1:12),rep(1:12)),
              tasmin=runif(24, min=-20, max=5),
              tasmax=runif(24, min=-1, max=30),
              pr=runif(24, min=0, max=300))

完整的数据集包含 900 个站点和 200 年。

我目前正在尝试嵌套循环,我意识到这不是最有效的,而且我正在努力实现它 - 代码如下:

sitesList <- as.character(unique(data1$Meteostation))
#yearsList<- unique(data1$Year)
bvList<-list()

for (i in c(1:length(unique(sitesList)))) {

   site<-filter(data1, Meteostation==sitesList[i])
   yearsList[i]<-unique(site$Year)

   for (j in c(1:length(yearsList))){

      timestep<-filter(site,Year==yearsList[j])
      tmin<-timestep$tasmin
      tmax<-timestep$tasmax
      pr<-timestep$pr

      bv<-biovars(pr,tmin,tmax)
      bvList[[j]]<- bv

}}

bv_all <- do.call(rbind, bvList)

我知道有很多更好的方法可以解决这个问题,并且一直在寻找 apply 和 dplyr 解决方案的变体,但我正在努力解决这个问题。非常感谢任何建议。

【问题讨论】:

    标签: r loops dplyr subset apply


    【解决方案1】:

    你可以使用 dplyr 包,也许如下?

    library(dplyr)
    data1 %>% 
        group_by(Meteostation, Year) %>%
        do(data.frame(biovars(.$pr, .$tasmin, .$tasmax)))
    

    【讨论】:

    • 谢谢,我之前尝试过,但汇总只产生 1 个值,因此无法处理 biovars 输出的 19 个值
    • 很抱歉 - 没有检查 biovars 输出。那会教我的。请参阅上面的编辑答案。
    • 感谢这似乎有效。以前没有遇到过 do() - 这真的很有用
    【解决方案2】:

    使用byrbind 结果。

    library("dismo")
    res <- do.call(rbind, by(data1, data1[c("Year", "Meteostation")], function(x) {
      cbind(x[c("Year", "Meteostation")], biovars(x$pr, x$tasmin, x$tasmax))
    }))
    

    生产

    head(res[, 1:10])
    #   Meteostation Year      bio1     bio2 bio3 bio4       bio5       bio6     bio7 bio8
    # 1      OBERHOF    1 12.932403 18.59525  100   NA 22.2300284   3.634777 18.59525   NA
    # 2      OBERHOF    2  5.620587  7.66064  100   NA  9.4509069   1.790267  7.66064   NA
    # 3      OBERHOF    3  0.245540 12.88662  100   NA  6.6888506  -6.197771 12.88662   NA
    # 4      OBERHOF    4  5.680438 45.33159  100   NA 28.3462326 -16.985357 45.33159   NA
    # 5      OBERHOF    5 -6.971906 16.83037  100   NA  1.4432801 -15.387092 16.83037   NA
    # 6      OBERHOF    6 -7.915709 14.63323  100   NA -0.5990945 -15.232324 14.63323   NA
    

    【讨论】:

    • 谢谢 - 我认为这非常有效。我现在唯一不确定的是如何将年份和气象站与结果联系起来?
    • 感谢 - 对于我的数据,它似乎每年都在重复结果/观察结果,因此数据集的增长幅度很大。上面的 dplyr 解决方案似乎避免了这种情况
    猜你喜欢
    • 2013-10-25
    • 1970-01-01
    • 2018-07-08
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 2019-01-14
    • 2021-11-17
    • 1970-01-01
    相关资源
    最近更新 更多