2016-08-02 12 views
1

我的數據是這樣的,並已進行排序:用相同的ID創建一個包含以前的值新列

> dput(df) 
structure(list(id = c(1, 2, 3, 3, 2, 2, 1), x = c(20, 40, 70, 
70, 80, 40, 70)), .Names = c("id", "x"), row.names = c(NA, -7L 
), class = "data.frame") 

> df 
    id x 
1 1 20 
2 2 40 
3 3 70 
4 3 70 
5 2 80 
6 2 40 
7 1 70 

我需要創建一個包含x具有相同id於前值的新列。所以結果應該是:

> df 
    id x old_x 
1 1 20 70 
2 2 40 80 
3 3 70 70 
4 3 70 NA 
5 2 80 40 
6 2 40 NA 
7 1 70 NA 

我能做到這樣:

for (i in 1:nrow(df)){ 
    id0 = df$id[i] 
    j = i + match(id0 , df$id[i+1:nrow(df)]) 
    df$old_x[i] = df$x[j] 
} 

,但它過於緩慢。什麼是最好的方法來做到這一點?

感謝您的幫助!

+0

以前的值還是下一個值?您的輸出是下一個值。如果它是以前的值,則使用'lag'而不是'lead' – Sumedh

+0

我的意思是'previous',因爲我的數據實際上是按降序排列的。 – Scarabee

回答

3

使用dplyr

library(dplyr) 
df %>% group_by(id) %>% mutate(old_x = lead(x)) 

#Source: local data frame [7 x 3] 
#Groups: id [3] 

#  id  x old_x 
# <dbl> <dbl> <dbl> 
#1  1 20 70 
#2  2 40 80 
#3  3 70 70 
#4  3 70 NA 
#5  2 80 40 
#6  2 40 NA 
#7  1 70 NA 
+0

謝謝,這是我的數據集上最快的方法。 – Scarabee

1

這裏是一個基R法與avetail

df$old_x <- ave(df$x, df$id, FUN=function(i) c(tail(i, -1), NA)) 

df 
    id x old_x 
1 1 20 70 
2 2 40 80 
3 3 70 70 
4 3 70 NA 
5 2 80 40 
6 2 40 NA 
7 1 70 NA 
2

我們可以使用data.table。將'data.frame'轉換爲'data.table'(setDT(df)),按'id'分組,我們將'x'中的lead值指定爲(:=)到'old_x'。這應該是非常快的,因爲我們正在分配。

library(data.table) 
setDT(df)[,old_x := shift(x, type = "lead") , by = id] 
df 
# id x old_x 
#1: 1 20 70 
#2: 2 40 80 
#3: 3 70 70 
#4: 3 70 NA 
#5: 2 80 40 
#6: 2 40 NA 
#7: 1 70 NA 
相關問題