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

私がやりたいことは、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 ループの反復ごとに、値が失われるか上書きされるという問題が発生しています。私はいくつかの調査を行いましたが、 for ループがデータフレームで「予期しないこと」を行うという不思議な情報以外のものを見つけることができました.

それで、誰も知っていますか:

a) データ フレームへの変更を反復を通じて永続化する方法は? ループを使用してデータ フレームを操作するときに、どのような「予期しないこと」が予想されるかを知りたいです。

および/または

b) よりエレガントなソリューション。私は非常に複雑なことを行うときに apply や ddply などを使用するのに苦労していますが、この例から学ぶことができるかもしれません。

ありがとうございました!

ジャレド

4

2 に答える 2

3

ここでa を使用する必要はありませんloop

  1. ddply/transform を使用して年ごとにグループ化し、結果として data.frame を取得します
  2. 累積降水量を計算する cumsum
  3. rev 前進する

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
于 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 に答える