如何在R中模仿ROW_NUMBER()OVER(...)

时间:2017-05-03 19:06:28

标签: r

为了随着时间的推移操纵/汇总数据,我通常使用SQL ROW_NUMBER()OVER(PARTITION by ...)。我是R的新手,所以我试图重新创建我在SQL中创建的表。包sqldf不允许OVER子句。示例表:

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     

我希望我的最终表能够包括第二个实例之后每天的前两个实例的平均值(两者都是第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与日期相关的事实来形成我的答案(即原始表格可以按照随机日期顺序重新排列,代码仍然有效)。如果您需要更多详细信息,请告诉我,谢谢您的帮助!

1 个答案:

答案 0 :(得分:0)

宽度为2时,您可能会滞后zoo::rollapplyr。在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