2012-06-24 36 views
0

我試圖計算數據框中的已用時間,其中已用時間的「開始」值取決於因子列中的因子列的值數據幀。 (簡單來說,我會將時間值視爲數字而不是時間對象 - 我的問題是關於拆分應用組合,而不是時間對象)。我的數據幀是這樣的:計算已過去的「次數」,其中參考時間取決於一個因子

df <- data.frame(id=gl(2, 3, 5, labels=c("a", "b")), time=1:5) 

我想通過減去每個因子水平的最短時間由每次(儘管這個例子的目的,我會只處理數值計算經過的時間,而不是時間值)。所以我想分割數據幀id,從y列中的每個元素中減去最小值y,然後返回一個包含轉換值的向量(或數據幀)。我想最終得到類似於:

> dfTrans 
id time elapsed 
a  1  0 
a  2  1 
a  3  2 
b  4  0 
b  5  1 

似乎是plyr的完美任務,但我無法找到簡單的解決方案。

我能想出的最好的是

elapsed <- dlply(df, .(id), function(x) x$time - min(x$time)) 
elapsed_comb <- NA 
for(i in 1:length(names(elapsed))) { 
    elapsed_comb <- c(elapsed_comb, elapsed[[i]]) 
} 
elapsed_comb <- elapsed_comb[-1] 
df$elapsed <- elapsed_comb 

這是不雅,似乎脆弱。當然有更好的方法?

回答

3

的「大道」的功能是你應該考慮的時候,結果是要與向量的第一件事長度與數據幀中的行數相同:

df$elapsed <- ave(df$time, df$id, FUN=function(x) x -min(x)) 
df 
    id time elapsed 
1 a 1  0 
2 a 2  1 
3 a 3  2 
4 b 4  0 
5 b 5  1 
2

這裏是一個ddply解決

ddply(df, .(id), summarize, time = time, elapsed = seq(length(id))-1) 

和一個使用RLE代替

df$elapsed <- unlist(sapply(rle(as.numeric(df$id))$lengths, seq))-1 
+0

不會使用'transform'會更自然:'ddply(d f,。(id),transform,elapsed = time - min(time))'? – joran

+0

可能。這不是我想到的。我一整天都在學習測量理論,而我的頭腦也不太正常。 – Dason

+0

呃。我的同情心。喝一杯啤酒,讓你的大腦再次正常工作。 – joran