我是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等,也许我可以从这个例子中学习。
谢谢!
贾里德
答案 0 :(得分:3)
此处无需使用loop
。
你只需要改变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
答案 1 :(得分: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