2017-05-03 65 views
1

要隨着時間的推移操作/彙總數據,我通常使用SQL ROW_NUMBER()OVER(PARTITION by ...)。我是R新手,所以我試圖重新創建表格,否則我會在SQL中創建表格。包sqldf不允許OVER子句。示例表:如何模仿ROW_NUMBER()O(...)R

ID Day Person Cost 
1  1  A  50  
2  1  B  25  
3  2  A  30  
4  3  B  75  
5  4  A  35  
6  4  B  100  
7  6  B  65  
8  7  A  20  

我希望我的決賽桌,包括每一天的前2個實例的平均他們的第二個實例後(對於第4天):

ID Day Person Cost  Prev2 
5  4  A  35  40 
6  4  B  100 50 
7  6  B  65  90 
8  7  A  20  35 

我一直在努力玩aggregate,但我不太確定如何分區或限定功能。理想情況下,我不希望使用這樣的事實:id與日期形成我的答案(即原始表可以重新排列隨機日期順序和代碼仍然工作)。如果您需要更多詳細信息,請告知我,感謝您的幫助!

+0

如果您使用PostgreSQL後端,則可以將OVER與sqldf一起使用。 –

回答

0

你可以滯後zoo::rollapplyr隨着2.在dplyr的寬度,

library(dplyr) 

df %>% arrange(Day) %>% # sort 
    group_by(Person) %>% # set grouping 
    mutate(Prev2 = lag(zoo::rollapplyr(Cost, width = 2, FUN = mean, fill = NA))) 
#> Source: local data frame [8 x 5] 
#> Groups: Person [2] 
#> 
#>  ID Day Person Cost Prev2 
#> <int> <int> <fctr> <int> <dbl> 
#> 1  1  1  A 50 NA 
#> 2  2  1  B 25 NA 
#> 3  3  2  A 30 NA 
#> 4  4  3  B 75 NA 
#> 5  5  4  A 35 40.0 
#> 6  6  4  B 100 50.0 
#> 7  7  6  B 65 87.5 
#> 8  8  7  A 20 32.5 

或全部dplyr,

df %>% arrange(Day) %>% group_by(Person) %>% mutate(Prev2 = (lag(Cost) + lag(Cost, 2))/2) 

返回同樣的事情。在基地,

df <- df[order(df$Day), ] 

df$Prev2 <- ave(df$Cost, df$Person, FUN = function(x){ 
    c(NA, zoo::rollapplyr(x, width = 2, FUN = mean, fill = NA)[-length(x)]) 
}) 

df 
#> ID Day Person Cost Prev2 
#> 1 1 1  A 50 NA 
#> 2 2 1  B 25 NA 
#> 3 3 2  A 30 NA 
#> 4 4 3  B 75 NA 
#> 5 5 4  A 35 40.0 
#> 6 6 4  B 100 50.0 
#> 7 7 6  B 65 87.5 
#> 8 8 7  A 20 32.5 

或沒有動物園,

df$Prev2 <- ave(df$Cost, df$Person, FUN = function(x){ 
    (c(NA, x[-length(x)]) + c(NA, NA, x[-(length(x) - 1):-length(x)]))/2 
}) 

它做同樣的事情。如果您想要刪除NA行,請使用tidyr::drop_na(Prev2)na.omit

+0

感謝您的回覆!我在不同的教程中使用過dplyr,但我從未真正將它用於我自己的「項目」。有時間潛入 – CoolGuyHasChillDay