R中的增量指示器列

Increment indicator column in R

我有以下数据,我正在尝试创建一个指示器列来跟踪 id 值的增量。

df <- data.frame(id=c(1,1,1,1,1,1,1,2,2,2,3,3,4),
         rank=c(1,2,3,1,1,1,2,2,3,1,1,2,3),dates=c('2019-06-15','2019-07-15','2019-08-15','2019-09-15','2019-10-15','2019-11-15','2019-12-15',
                 '2019-10-15','2019-11-15','2019-12-15',
                 '2019-11-15','2019-12-15','2019-12-15'),new_col=c(0,1,1,1,1,1,1,0,1,1,0,1,0)
         )

这里日期的顺序很重要。

setDT(df)[order(id,dates),]

期望的输出

   id  rank   dates     new_col
1   1    1   2019-06-15       0
2   1    2   2019-07-15       1
3   1    3   2019-08-15       1
4   1    1   2019-09-15       1
5   1    1   2019-10-15       1
6   1    1   2019-11-15       1
7   1    2   2019-12-15       1
8   2    2   2019-10-15       0
9   2    3   2019-11-15       1
10  2    1   2019-12-15       1
11  3    1   2019-11-15       0
12  3    2   2019-12-15       1
13  4    3   2019-12-15       0

更新输入数据-

df <- data.frame(id=c(1,1,1,1,1,1,1,2,2,2,3,3,4,5,5,5),
             rank=c(1,2,3,1,1,1,2,2,3,1,1,2,3,1,1,1),dates=c('2019-06-15','2019-07-10','2019-08-15','2019-09-15','2019-10-15','2019-11-15','2019-12-15',
                     '2019-10-15','2019-11-15','2019-12-15',
                     '2019-11-15','2019-12-15','2019-12-15','2019-10-15','2019-11-15','2019-12-15'))

更新输出-

      id   rank  dates       new

 1     1     1 2019-06-15     0
 2     1     2 2019-07-10     1
 3     1     3 2019-08-15     1
 4     1     1 2019-09-15     1
 5     1     1 2019-10-15     1
 6     1     1 2019-11-15     1
 7     1     2 2019-12-15     1
 8     2     2 2019-10-15     0
 9     2     3 2019-11-15     1
10     2     1 2019-12-15     1
11     3     1 2019-11-15     0
12     3     2 2019-12-15     1
13     4     3 2019-12-15     0
14     5     1 2019-10-15     0
15     5     1 2019-11-15     0
16     5     1 2019-12-15     0

假设你的数据框按照你想要的方式排序,这里是一个使用 base R 的解决方案:

df$new_col_2 = c(0, 1 - diff(df$id))

> df
   id rank      dates new_col new_col_2
1   1    1 2019-06-15       0         0
2   1    2 2019-07-15       1         1
3   1    3 2019-08-15       1         1
4   1    1 2019-09-15       1         1
5   1    1 2019-10-15       1         1
6   1    1 2019-11-15       1         1
7   1    2 2019-12-15       1         1
8   2    2 2019-10-15       0         0
9   2    3 2019-11-15       1         1
10  2    1 2019-12-15       1         1
11  3    1 2019-11-15       0         0
12  3    2 2019-12-15       1         1
13  4    3 2019-12-15       0         0

按'id'

分组后,我们可以在'dates'上使用diff
library(dplyr)
df %>% 
   group_by(id) %>%       
   mutate(new = c(0, diff(as.Date(dates)) > 0))
# A tibble: 13 x 5
# Groups:   id [4]
#      id  rank dates      new_col   new
#   <dbl> <dbl> <fct>        <dbl> <dbl>
# 1     1     1 2019-06-15       0     0
# 2     1     2 2019-07-15       1     1
# 3     1     3 2019-08-15       1     1
# 4     1     1 2019-09-15       1     1
# 5     1     1 2019-10-15       1     1
# 6     1     1 2019-11-15       1     1
# 7     1     2 2019-12-15       1     1
# 8     2     2 2019-10-15       0     0
# 9     2     3 2019-11-15       1     1
#10     2     1 2019-12-15       1     1
#11     3     1 2019-11-15       0     0
#12     3     2 2019-12-15       1     1
#13     4     3 2019-12-15       0     0

更新

df %>% 
    group_by(id) %>% 
    mutate(new = +(c(FALSE, diff(as.Date(dates)) > 0) & 
       (any(rank  != lag(rank, default = first(rank))))))
# A tibble: 16 x 4
# Groups:   id [5]
#      id  rank dates        new
#   <dbl> <dbl> <fct>      <int>
# 1     1     1 2019-06-15     0
# 2     1     2 2019-07-10     1
# 3     1     3 2019-08-15     1
# 4     1     1 2019-09-15     1
# 5     1     1 2019-10-15     1
# 6     1     1 2019-11-15     1
# 7     1     2 2019-12-15     1
# 8     2     2 2019-10-15     0
# 9     2     3 2019-11-15     1
#10     2     1 2019-12-15     1
#11     3     1 2019-11-15     0
#12     3     2 2019-12-15     1
#13     4     3 2019-12-15     0
#14     5     1 2019-10-15     0
#15     5     1 2019-11-15     0
#16     5     1 2019-12-15     0

您可以使用 rep 并安排日期,因为您说它们很重要:

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union

df %>%
  arrange(id, dates) %>% 
  group_by(id) %>%
  mutate(new_col2 = c(0, rep(1, (n() - 1))))
#> # A tibble: 13 x 5
#> # Groups:   id [4]
#>       id  rank dates      new_col new_col2
#>    <dbl> <dbl> <fct>        <dbl>    <dbl>
#>  1     1     1 2019-06-15       0        0
#>  2     1     2 2019-07-15       1        1
#>  3     1     3 2019-08-15       1        1
#>  4     1     1 2019-09-15       1        1
#>  5     1     1 2019-10-15       1        1
#>  6     1     1 2019-11-15       1        1
#>  7     1     2 2019-12-15       1        1
#>  8     2     2 2019-10-15       0        0
#>  9     2     3 2019-11-15       1        1
#> 10     2     1 2019-12-15       1        1
#> 11     3     1 2019-11-15       0        0
#> 12     3     2 2019-12-15       1        1
#> 13     4     3 2019-12-15       0        0