我認爲這會爲你工作。當遇到差異問題時,通過將0作爲第一個數字加長矢量。
df <- df[order(df$id, df$year), ]
sdf <-split(df, df$id)
df$actual <- as.vector(sapply(seq_along(sdf), function(x) diff(c(0, sdf[[x]][,2]))))
df[order(as.numeric(rownames(df))),]
有很多方法可以做到這一點,但這一個是相當快,並使用基地。
這裏的臨近利用骨料,並通過這個問題的第二&第三種方式:
彙總:
df <- df[order(df$id, df$year), ]
diff2 <- function(x) diff(c(0, x))
df$actual <- c(unlist(t(aggregate(value~id, df, diff2)[, -1])))
df[order(as.numeric(rownames(df))),]
由:
df <- df[order(df$id, df$year), ]
diff2 <- function(x) diff(c(0, x))
df$actual <- unlist(by(df$value, df$id, diff2))
df[order(as.numeric(rownames(df))),]
plyr
df <- df[order(df$id, df$year), ]
df <- data.frame(temp=1:nrow(df), df)
library(plyr)
df <- ddply(df, .(id), transform, actual=diff2(value))
df[order(-df$year, df$temp),][, -1]
它給你的最終產品:
> df[order(as.numeric(rownames(df))),]
id value year actual
1 1 21 3 5
2 2 26 3 16
3 3 26 3 14
4 4 26 3 10
5 5 29 3 14
6 1 16 2 10
7 2 10 2 5
8 3 12 2 10
9 4 16 2 7
10 5 15 2 13
11 1 6 1 6
12 2 5 1 5
13 3 2 1 2
14 4 9 1 9
15 5 2 1 2
編輯:避免環路
我可以建議避免循環和車削什麼我給你進入一個函數(對我而言,解決方案是最容易的解決方案),並將它們灌輸到您希望的兩列中。
set.seed(1234) #make new data with another numeric column
x <- data.frame(id=1:5, value=sample(20:30, 5, replace=T), year=3)
y <- data.frame(id=1:5, value=sample(10:19, 5, replace=T), year=2)
z <- data.frame(id=1:5, value=sample(0:9, 5, replace=T), year=1)
df <- rbind(x, y, z)
df <- df.rep <- data.frame(df[, 1:2], new.var=df[, 2]+sample(1:5, nrow(df),
replace=T), year=df[, 3])
df <- df[order(df$id, df$year), ]
diff2 <- function(x) diff(c(0, x)) #function one
group.diff<- function(x) unlist(by(x, df$id, diff2)) #answer turned function
df <- data.frame(df, sapply(df[, 2:3], group.diff)) #apply group.diff to col 2:3
df[order(as.numeric(rownames(df))),] #reorder it
當然,你必須重新命名這些,除非你使用transform
爲:
df <- df[order(df$id, df$year), ]
diff2 <- function(x) diff(c(0, x)) #function one
group.diff<- function(x) unlist(by(x, df$id, diff2)) #answer turned function
df <- transform(df, actual=group.diff(value), actual.new=group.diff(new.var))
df[order(as.numeric(rownames(df))),]
這將取決於你有多少變量,這樣做是爲了。
奇怪。我的'set.seed()'顯然不起作用。我用實際數字更新了它。 – Andrew 2012-03-04 06:52:15
這太棒了!是否有一種簡單的方法可以使任何這些函數適用於任意數量的列,例如,如果存在2+錯誤彙總變量:'x < - data.frame(id = 1:5,value = sample(20:30, 5,replace = T),value1 = sample(20:30,5,replace = T),year = 3)'等等? – Andrew 2012-03-04 17:19:51
我的意思是,我試圖做的是運行相同的'as.vector(sapply(seq_along(...'一次爲多個列的函數(不只是2)。我基本上試圖運行該功能在列的範圍內使用'lapply'(2:x) – Andrew 2012-03-04 17:30:20