2011-02-25 50 views
2

我有一個包含三列fyear,ticdcvt(對於會計年度,股票代碼和總可轉換債務)的長數據框。大約有18個財政年度和幾千個代理商。我想添加一個指標變量,每當dcvt從一年上升到下一個時,這個變量就是一個。將指標變量添加到長數據框中,以便當值從一年增加到下一個時

我試過ddply,但我失去了fyear列,並不確定如何找回來。

library(plyr) 
temp <- data.frame(fyear = rep(1992:2009, 10), tic = rep(letters[1:10], each = 18), dcvt = rnorm(180, 200, 10)) 
my.fun <- function(x) x <- c(0, ifelse(tail(x, -1) - head(x, -1) > 0, 1, 0)) 
temp2 <- ddply(temp, "tic", colwise(my.fun, "dcvt")) 

我也試圖轉換爲寬與reshape2包,然後運行for循環,當然,那沒完沒了。

有沒有一種方法可以快速做到這一點?我應該製作一個寬的zoo對象,然後使用diff?如果可以,我想避免通過時間序列。謝謝!使用

回答

5

變換分析在ddply有時幫助我們大大:

ddply(temp, .(tic), transform, dcvt=c(0, diff(dcvt)>0)) 
+0

謝謝!菜鳥的錯誤;我甚至在幾個月前看到'ddply'裏面的'變換'! – 2011-02-26 00:34:08

2

ddpy()處理這種尺寸(10^2)相當不錯的數據集。但是,對於大型數據集,並在那裏你不一定需要返回一個完整的數據幀的情況下,我會考慮以下do.call + lapply解決方案:

my.fun <- function(cur.tic){ 
    as.numeric(diff(temp$dcvt[temp$tic == cur.tic]) > 0) 
} 

do.call("c", lapply(unique(temp$tic), my.fun)) 

爲了證明性能收益(不公平給出的向量對據幀的問題),我把OP的樣本數據,創建^ 4,10^5和10^6級10的新的數據幀,然後跑去system.time()上@ kohske的ddply解決方案和上面的解決方案:

原始數據(10^2):

> system.time(do.call("c", lapply(unique(temp$tic), my.fun))) 
    user system elapsed 
    0.000 0.000 0.003 
> system.time(ddply(temp, .(tic), transform, dcvt=c(0, diff(dcvt)>0))) 
    user system elapsed 
    0.020 0.000 0.013 

10^4的樣本數據

> system.time(do.call("c", lapply(unique(temp.2$tic), my.fun))) 
    user system elapsed 
    0.000 0.000 0.002 
> system.time(ddply(temp.2, .(tic), transform, dcvt=c(0, diff(dcvt)>0))) 
    user system elapsed 
    0.040 0.000 0.036 

10^5個樣本數據

> system.time(do.call("c", lapply(unique(temp.3$tic), my.fun))) 
    user system elapsed 
    0.000 0.000 0.004 
> system.time(ddply(temp.3, .(tic), transform, dcvt=c(0, diff(dcvt)>0))) 
    user system elapsed 
    0.270 0.000 0.279 

10^6個採樣數據

> system.time(do.call("c", lapply(unique(temp.4$tic), my.fun))) 
    user system elapsed 
    0.010 0.000 0.018 
> system.time(ddply(temp.4, .(tic), transform, dcvt=c(0, diff(dcvt)>0))) 
    user system elapsed 
    6.110 0.070 6.186 

不是抱怨約ddply() - 相反,只是努力分享一些我發現最有用的代碼,同時處理一個非常類似的問題,最近有一個很大的數據集。

+1

由於ddply返回一個數據框並且函數返回一個向量,所以並不是一個公平的比較。 ave可能會更快 – hadley 2011-02-27 05:18:34

+0

+1這是一個很棒的觀點,@hadley。我並不是說我的評論是關於'ddply'的一個抱怨,而是我詳細闡述了一種方法,我發現這種方法對於我最近研究的一個非常大的數據集(10^7)非常有效。編輯我的答案澄清這一點! – ashaw 2011-02-27 21:23:24

相關問題