3

我是 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

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

我知道,理想情况下,我会避免显式循环,但我被以下事实难住了:我似乎需要计算一个子集的总和,该子集根据我正在使用的观察结果而变化。因此,使用 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 循环的每次迭代中值丢失或覆盖的情况下发生了一些事情。我做了一些研究,但除了 for 循环对数据帧做“意外事情”的神秘信息之外,还能找到任何东西。

那么,有没有人知道:

a)如何使对数据框的更改在迭代中持续存在?我很想知道在使用循环对数据帧进行操作时我可能会期待什么“意外的事情”。

和/或

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

谢谢!

贾里德

4

2 回答 2

3

不需要在loop这里使用 a 。

  1. 使用 ddply/transform 按年份分组,结果得到一个 data.frame
  2. 和 cumsum 计算累积降水量
  3. rev 前进

您只需在 1Aug(第 213 天)之前更改 5Jan:

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
于 2013-11-09T19:52:18.367 回答
1

没有检查您的代码,但它应该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
于 2013-11-09T19:07:14.740 回答