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
我有以下数据,我正在尝试创建一个指示器列来跟踪 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