2017-11-11 23 views
2

我有一个像下面这样的数据框df - 它在几个月内获得/失去了积分。数据帧 - 访问前一行

name month  agg_points 
A 2017-04-01 1 
B 2017-04-01 3 
C 2017-04-01 0 
A 2017-05-01 2 
B 2017-05-01 5 
C 2017-05-01 2 
A 2017-06-01 4 
B 2017-06-01 5 
C 2017-06-01 1 

我需要找到/获得净点失去了一个每月的基础 - 这将意味着从当月的点减去前一个月的分。如何访问df上月的积分?

预期输出

name month  net_points 
A 2017-04-01 1 
B 2017-04-01 3 
C 2017-04-01 0 
A 2017-05-01 1 
B 2017-05-01 2 
C 2017-05-01 2 
A 2017-06-01 2 
B 2017-06-01 0 
C 2017-06-01 -1 

回答

3

随着dplyr,你可能在你grouparrange后使用lag功能行适当:

library(dplyr) 
df %>% 
    group_by(name) %>% 
    arrange(month, .by_group = TRUE) %>% 
    mutate(net_points = agg_points - lag(agg_points, default = 0)) %>% 
    arrange(month) 

#> # A tibble: 9 x 4 
#> # Groups: name [3] 
#> name  month agg_points net_points 
#> <chr>  <chr>  <int>  <int> 
#> 1  A 2017-04-01   1   1 
#> 2  B 2017-04-01   3   3 
#> 3  C 2017-04-01   0   0 
#> 4  A 2017-05-01   2   1 
#> 5  B 2017-05-01   5   2 
#> 6  C 2017-05-01   2   2 
#> 7  A 2017-06-01   4   2 
#> 8  B 2017-06-01   5   0 
#> 9  C 2017-06-01   1   -1 

数据

df <- read.table(text = "name month  agg_points 
A 2017-04-01 1 
B 2017-04-01 3 
C 2017-04-01 0 
A 2017-05-01 2 
B 2017-05-01 5 
C 2017-05-01 2 
A 2017-06-01 4 
B 2017-06-01 5 
C 2017-06-01 1", header = TRUE, stringsAsFactors = FALSE) 
1

方式一:

with(df, { 
    x <- xtabs(agg_points ~ month + name) 
    x[-1, ] <- diff(x) 
    as.data.frame(x, responseName = 'net_points') 
}) 
#  month name net_points 
#1 2017-04-01 A   1 
#2 2017-05-01 A   1 
#3 2017-06-01 A   2 
#4 2017-04-01 B   3 
#5 2017-05-01 B   2 
#6 2017-06-01 B   0 
#7 2017-04-01 C   0 
#8 2017-05-01 C   2 
#9 2017-06-01 C   -1 
1

您可以创建新的临时变量滞后和使用X3 - lag获得net_points

library(readr) 
df <- read_csv(
    "A,2017-04-01,1 
    B,2017-04-01,3 
    C,2017-04-01,0 
    A,2017-05-01,2 
    B,2017-05-01,5 
    C,2017-05-01,2 
    A,2017-06-01,4 
    B,2017-06-01,5 
    C,2017-06-01,1", 
    col_names = F 
) 
str(df) 
library(dplyr) 
df %>% group_by(X1) %>% mutate(lag = lag(X3), diff = ifelse(!is.na(lag), X3 - lag, X3)) %>% 
    select(-lag) 

 X1   X2 X3 diff 
    <chr>  <date> <int> <int> 
1  A 2017-04-01  1  1 
2  B 2017-04-01  3  3 
3  C 2017-04-01  0  0 
4  A 2017-05-01  2  1 
5  B 2017-05-01  5  2 
6  C 2017-05-01  2  2 
7  A 2017-06-01  4  2 
8  B 2017-06-01  5  0 
9  C 2017-06-01  1 -1 
0

我markdly答案的data.table相当于:

library(data.table) 
DT <- setDT(df) 
setkey(DT,month) 
x <- DT[, list(netpoint = diff(agg_points), month = .SD[-1,month]),by = name] 

x是data_table与差异值。然后,我们合并x和DT

DT <- x[DT, on = .(name,month)][,c("name","month","agg_points","netpoint")] 

,并添加网格点的(等于agg_points)

DT[,netpoint :={netpoint[1]<-agg_points[1]; netpoint},by=name] 

其中给出

name  month agg_points netpoint 
1: A 2017-04-01   1  1 
2: B 2017-04-01   3  3 
3: C 2017-04-01   0  0 
4: A 2017-05-01   2  1 
5: B 2017-05-01   5  2 
6: C 2017-05-01   2  2 
7: A 2017-06-01   4  2 
8: B 2017-06-01   5  0 
9: C 2017-06-01   1  -1 

到markdly答案将是一个更接近的方式第一值:

DT <- setDT(df) 
setkey(DT,month) 
DT[,netpoint := agg_points - c(NA, agg_points[-.N]), by = name] 

但我仍然需要做

DT[,netpoint :={netpoint[1]<-agg_points[1]; netpoint},by=name] 

填写第一行,这让我感到失望。任何人都有更好的方法?