2012-05-10 19 views
4

この質問に関連して、私は「新しい」質問がオリジナルと直接関係していないので、明確にするために別の質問をすることにしました。簡単に言えば、私はddplyを使用して3年間のそれぞれの値を累積的に合計しています。私のコードでは、最初の年のデータが2番目と3番目の列に繰り返されます。私の推測では、各1年分のチャンクはコラム全体にコピーされていますが、なぜそれが理解できません。R:毎年累積データを繰り返す

Q.指定した列の右の行に、年ごとの累積合計値を取得するにはどうすればよいですか。

[編集:forループなど]は重要です。新しい列を手動で計算するのではなく、列名のリストに基づいて自動的に新しい列を計算したいのです。列名のリストをループの反復する。]

enter image description here

それは突然に問題がなければ、むしろ厄介であるので、私は頻繁にddplyとCUMSUM組み合わせを使用しています。

[編集:このコードは以下のチェースの答えは@に基づいており、私は上の定住溶液に更新されました]

require(lubridate) 
require(plyr) 
require(xts) 
require(reshape) 
require(reshape2) 

set.seed(12345) 
# create dummy time series data 
monthsback <- 24 
startdate <- as.Date(paste(year(now()),month(now()),"1",sep = "-")) - months(monthsback) 
mydf <- data.frame(mydate = seq(as.Date(startdate), by = "month", length.out = monthsback), 
        myvalue1 = runif(monthsback, min = 600, max = 800), 
        myvalue2 = runif(monthsback, min = 1900, max = 2400), 
        myvalue3 = runif(monthsback, min = 50, max = 80), 
        myvalue4 = runif(monthsback, min = 200, max = 300)) 

mydf$year <- as.numeric(format(as.Date(mydf$mydate), format="%Y")) 
mydf$month <- as.numeric(format(as.Date(mydf$mydate), format="%m")) 

# Select columns to process 
newcolnames <- c('myvalue1','myvalue4','myvalue2') 

# melt n' cast 
mydf.m <- mydf[,c('mydate','year',newcolnames)] 
mydf.m <- melt(mydf.m, measure.vars = newcolnames) 
mydf.m <- ddply(mydf.m, c("year", "variable"), transform, newcol = cumsum(value)) 
mydf.m <- dcast(mydate ~ variable, data = mydf.m, value.var = "newcol") 
colnames(mydf.m) <- c('mydate',paste(newcolnames, "_cum", sep = "")) 
mydf <- merge(mydf, mydf.m, by = 'mydate', all = FALSE) 
mydf 

答えて

4

私は本当にそこループのためにあなたに従っていませんが、あなたは過度に複雑さ物事? transformddplyを直接使用することはできませんか?

#Make sure it's ordered properly 
mydf <- mydf[order(mydf$year, mydf$month),] 

#Use ddply to calculate the cumsum by year: 
ddply(mydf, "year", transform, 
     cumsum1 = cumsum(myvalue1), 
     cumsum2 = cumsum(myvalue2)) 
#---------- 
     mydate myvalue1 myvalue2 year month cumsum1 cumsum2 
1 2010-05-01 744.1808 264.4543 2010  5 744.1808 264.4543 
2 2010-06-01 775.1546 238.9828 2010  6 1519.3354 503.4371 
3 2010-07-01 752.1965 269.8544 2010  7 2271.5319 773.2915 
.... 
9 2011-01-01 745.5411 218.7712 2011  1 745.5411 218.7712 
10 2011-02-01 797.9474 268.1834 2011  2 1543.4884 486.9546 
11 2011-03-01 606.9071 237.0104 2011  3 2150.3955 723.9650 
... 
21 2012-01-01 690.7456 225.9681 2012  1 690.7456 225.9681 
22 2012-02-01 665.3505 232.1225 2012  2 1356.0961 458.0906 
23 2012-03-01 793.0831 206.0195 2012  3 2149.1792 664.1101 

EDITは - 私はこのマシン上でRを持っていないので、これはテストされていないが、これは私が考えていたものです:

require(reshape2) 
mydf.m <- melt(mydf, measure.vars = newcolnames) 
mydf.m <- ddply(mydf.m, c("year", "variable"), transform, newcol = cumsum(value)) 
dcast(mydate + year + month ~ variable, data = mydf.m, value.var = "newcol") 
+0

はあなたに@Chaseをありがとうございます。私が小さな固定グループ、例えば2〜3列を扱っているとき、私は 'ddply'と' transform'を直接使用できます。そして、昨日、私は12のデータ系列に対してこれを行う必要があることを発見しました。私は、現在の各値を直接コーディングする私のアプローチは規模が大きく、再考する必要があるという結論に導きました。 'for'ループは、これらの年間実行合計(およびその他の一般的な計算も同様)を保持する列の作成を自動化しようとする私の試みです。 – SlowLearner

+0

@SlowLearner - gotcha。まず第一に、あなたのデータを長いフォーマットに ''溶かす '' ddply''を 'year'と' variable'でグループ化してから、キャストしてワイドフォーマットに戻してください。 – Chase

+0

ありがとう。私は、あなたが意味することを概念化することに問題があります。私はあなたが 'for'ループのジャンクを意味すると思います...私は' mydf < - melt(mydf、id = c( 'mydate'、 'year'、 'month'))を試しました mydf $ newcol < - 1 mydfcolnames(mydf)[colnames(mydf)== "newcol"] < - paste(変数、 "_cuml"、sep = "newcol")< - ddply(mydf、 newcolをワイドフォーマットに戻すために最終的なキャストを実行することができないことを除いて、動作するように見えます。 "#:。msgstr"お元気ですか? – SlowLearner