繁体   English   中英

在迭代for循环时保留对R数据帧的更改

[英]Preserving changes to R data frame while iterating through for loop

我是Stackexchange的新手,所以如果我不正确地提出这个问题,我会提前道歉。

这是背景。 我试图根据春季的最后一天建立小麦的推荐种植日期,在干燥的夏季开始之前,人们可以合理地预计会看到至少10个以上的降雨。

我有一个如下所示的数据集:

    Site   Date Year DayOfYear DayofRun AveTemp MaxTemp MinTemp Precip TotPre
1 EelRiver 1/1/02 2002         1        1    53.6      57      51   1.01     NA
2 EelRiver 1/2/02 2002         2        2    52.5      64      43   1.30     NA
3 EelRiver 1/3/02 2002         3        3    46.6      60      42   0.56     NA
4 EelRiver 1/4/02 2002         4        4    45.7      57      41   0.00     NA
5 EelRiver 1/5/02 2002         5        5    51.0      57      46   0.53     NA
6 EelRiver 1/6/02 2002         6        6    57.9      60      55   1.70     NA

我想要做的是在TotPre列填充从该日期到8月1日的总降雨量。

我知道,理想情况下,我会避免使用显式循环,但我感到困惑的是,似乎我需要计算一个基于我正在使用的观察结果而变化的子集的总和。 所以,使用for循环,这是我尝试这样做的方式:

eelriverdata <- read.csv(file="EelRiverCamp.csv",head=TRUE,sep=",")

for (i in nrow(eelriverdata)) {

    tempYear <- eelriverdata[i,"Year"]
    AugIndex <- which(eelriverdata[,"Year"]==tempYear & eelriverdata[,"DayOfYear"] == 213)

    if (i < AugIndex) {
        Tot <- sum(eelriverdata[i:AugIndex,"Precip"])
        eelriverdata$TotPre[i] <- Tot
    }

    else {eelriverdata$TotPre[i] <- 0}

}

我遇到的问题是,只有TotPre中的最后一个观察结果才会在执行循环结束时填充,剩下的值保持为NA。 在for循环的每次迭代中,值丢失或被覆盖的地方都会发生一些事情。 我做了一些研究,但除了神秘的信息之外,还可以找到除了循环用数据框做出“意想不到的事情”的神秘信息。

那么,有谁知道:

a)如何通过迭代继续对数据框进行更改? 我很想知道在使用循环操作数据帧时我可能会遇到的“意想不到的事情”。

和/或

b)更优雅的解决方案。 在做任何非常复杂的事情时,我很难使用apply,ddply等,也许我可以从这个例子中学习。

谢谢!

贾里德

这里不需要使用loop

  1. 使用ddply / transform按年分组并获得data.frame作为结果
  2. 和积累来计算累积降水量
  3. 转而前进

你只需要改变5Jan 1Aug(第213天):

library(plyr)
ddply(dat,.(Year),transform, 
     TotPrecp= ifelse(DayOfYear > 5, NA,rev(cumsum(Precip))))

结果如下:

  Site   Date Year DayOfYear DayofRun AveTemp MaxTemp MinTemp Precip TotPre TotPrecp
1 EelRiver 1/1/02 2002         1        1    53.6      57      51   1.01     NA     5.10
2 EelRiver 1/2/02 2002         2        2    52.5      64      43   1.30     NA     3.40
3 EelRiver 1/3/02 2002         3        3    46.6      60      42   0.56     NA     2.87
4 EelRiver 1/4/02 2002         4        4    45.7      57      41   0.00     NA     2.87
5 EelRiver 1/5/02 2002         5        5    51.0      57      46   0.53     NA     2.31
6 EelRiver 1/6/02 2002         6        6    57.9      60      55   1.70     NA       NA

要回答你关于循环的问题主要是因为它们的副作用是危险的:

for (i in 1:10) x <- 2             ## create a global variable x
lapply (1:10, function(z) x <- 2)  ## SAFE don't create a gloable variable x

没有检查你的代码,但它应该是for (i in 1:nrow(eelriverdata)) {而不是for (i in nrow(eelriverdata)) {

以下是我的版本,你只用年份而不是所有行循环。

我不清楚一些问题,但尝试这种方法

试试这个:

set.seed(5)
tempdf=data.frame(year=rep(2002:2006, each=365), dayofyear=rep(1:365, times=5), prec=runif(365*5), totpre=0)

years=unique(tempdf$year)
for (i in 1:length(years)){
totpreindex<-which(tempdf[,"year"]==years[i] & tempdf[,"dayofyear"]==213)
totpre<-sum(tempdf[tempdf$year==years[i] & tempdf$dayofyear>0  & tempdf$dayofyear<213,"prec"])
tempdf[totpreindex,"totpre"]<-totpre
}

输出:

> tempdf[tempdf$totpre>0,]
     year dayofyear      prec   totpre
213  2002       213 0.4094868 108.9317
578  2003       213 0.2037912 109.2401
943  2004       213 0.3949180 112.0684
1308 2005       213 0.6600369 107.0455
1673 2006       213 0.5524957 102.6835

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM