R 跨行向量化迭代操作
我在这里看到了很多关于循环矢量化的问题,但是找不到任何涉及到基于下面一行单元格的值矢量化for循环以填充单元格的问题(如果我只是瞎了眼睛,请道歉…) 我有一个包含160万行工资和每个人开始赚取工资的日期的数据框。每个人都可以有多个工资,因此可以有多个行,每个行都有不同的更新日期 虚拟数据集的代码如下所示:R 跨行向量化迭代操作,r,for-loop,data.table,vectorization,R,For Loop,Data.table,Vectorization,我在这里看到了很多关于循环矢量化的问题,但是找不到任何涉及到基于下面一行单元格的值矢量化for循环以填充单元格的问题(如果我只是瞎了眼睛,请道歉…) 我有一个包含160万行工资和每个人开始赚取工资的日期的数据框。每个人都可以有多个工资,因此可以有多个行,每个行都有不同的更新日期 虚拟数据集的代码如下所示: df1 <- data.frame("id" = c(1,1,2,2,3,3,4,4,5,5,6,6), "salary" = c(15456,165
df1 <- data.frame("id" = c(1,1,2,2,3,3,4,4,5,5,6,6),
"salary" = c(15456,16594,
17364,34564,
34525,33656,
23464,23467,
16794,27454,
40663,42743),
"start_date" = sample(seq(as.Date('2016/01/01'),as.Date(Sys.Date()), by="day"), 12))
df1 <- df1[order(df1$id,df1$start_date),]
df1您可以使用库(data.table)
:
您可以使用库(data.table)
:
使用data.table和shift,您可以使用以下命令:
df1 <- data.table("id" = c(1,1,2,2,3,3,4,4,5,5,6,6),
"salary" = c(15456,16594,
17364,34564,
34525,33656,
23464,23467,
16794,27454,
40663,42743),
"start_date" = sample(seq(as.Date('2016/01/01'),as.Date(Sys.Date()), by="day"), 12))
df1 <- df1[order(id,start_date),]
df1[, EndDate := shift(start_date, type="lead"), id]
df1[is.na(EndDate), EndDate := Sys.Date()]
df1对于data.table和shift,您可以使用以下命令:
df1 <- data.table("id" = c(1,1,2,2,3,3,4,4,5,5,6,6),
"salary" = c(15456,16594,
17364,34564,
34525,33656,
23464,23467,
16794,27454,
40663,42743),
"start_date" = sample(seq(as.Date('2016/01/01'),as.Date(Sys.Date()), by="day"), 12))
df1 <- df1[order(id,start_date),]
df1[, EndDate := shift(start_date, type="lead"), id]
df1[is.na(EndDate), EndDate := Sys.Date()]
df1如果我理解你的问题,下面的基本R代码就可以了
df1$end <- ave(df1$start_date, df1$id, FUN=function(x) c(tail(x, -1) - 1, Sys.Date()))
如果我理解你的问题,下面的基本R代码将起作用
df1$end <- ave(df1$start_date, df1$id, FUN=function(x) c(tail(x, -1) - 1, Sys.Date()))
使用dplyr
软件包,您可以执行以下操作:
library(dplyr)
df1 %>%
group_by(id) %>%
mutate(end_date=lead(start_date-1,default=Sys.Date()))
返回:
id salary start_date end_date
<dbl> <dbl> <date> <date>
1 1 15456 2016-02-14 2016-03-02
2 1 16594 2016-03-03 2017-05-22
3 2 17364 2016-01-17 2016-11-28
4 2 34564 2016-11-29 2017-05-22
5 3 33656 2016-08-17 2016-11-25
6 3 34525 2016-11-26 2017-05-22
7 4 23464 2016-01-20 2017-05-05
8 4 23467 2017-05-06 2017-05-22
9 5 27454 2016-02-29 2016-12-15
10 5 16794 2016-12-16 2017-05-22
11 6 42743 2016-03-14 2017-01-29
12 6 40663 2017-01-30 2017-05-22
id工资开始日期结束日期
1 1 15456 2016-02-14 2016-03-02
2 1 16594 2016-03-03 2017-05-22
3 2 17364 2016-01-17 2016-11-28
4 2 34564 2016-11-29 2017-05-22
5 3 33656 2016-08-17 2016-11-25
6 3 34525 2016-11-26 2017-05-22
7 4 23464 2016-01-20 2017-05-05
8 4 23467 2017-05-06 2017-05-22
9 5 27454 2016-02-29 2016-12-15
10 5 16794 2016-12-16 2017-05-22
11 6 42743 2016-03-14 2017-01-29
12 6 40663 2017-01-30 2017-05-22
使用dplyr
软件包,您可以执行以下操作:
library(dplyr)
df1 %>%
group_by(id) %>%
mutate(end_date=lead(start_date-1,default=Sys.Date()))
返回:
id salary start_date end_date
<dbl> <dbl> <date> <date>
1 1 15456 2016-02-14 2016-03-02
2 1 16594 2016-03-03 2017-05-22
3 2 17364 2016-01-17 2016-11-28
4 2 34564 2016-11-29 2017-05-22
5 3 33656 2016-08-17 2016-11-25
6 3 34525 2016-11-26 2017-05-22
7 4 23464 2016-01-20 2017-05-05
8 4 23467 2017-05-06 2017-05-22
9 5 27454 2016-02-29 2016-12-15
10 5 16794 2016-12-16 2017-05-22
11 6 42743 2016-03-14 2017-01-29
12 6 40663 2017-01-30 2017-05-22
id工资开始日期结束日期
1 1 15456 2016-02-14 2016-03-02
2 1 16594 2016-03-03 2017-05-22
3 2 17364 2016-01-17 2016-11-28
4 2 34564 2016-11-29 2017-05-22
5 3 33656 2016-08-17 2016-11-25
6 3 34525 2016-11-26 2017-05-22
7 4 23464 2016-01-20 2017-05-05
8 4 23467 2017-05-06 2017-05-22
9 5 27454 2016-02-29 2016-12-15
10 5 16794 2016-12-16 2017-05-22
11 6 42743 2016-03-14 2017-01-29
12 6 40663 2017-01-30 2017-05-22
这适用于每个id的第一行,但将每个id的最后一行设置为第一行日期的前一天,而我在今天的日期之后。这适用于每个id的第一行,但将每个id的最后一行设置为第一行日期的前一天,而我在今天的日期之后。请参阅我答案的注释,他希望Sys.Date()
用于end\u Date
如果start\u Date
是每个id的最新日期,…我也在相同的陷阱中运行。啊哈。感谢您的澄清。请参阅我回答中的评论,他希望Sys.Date()
用于end\u Date
如果start\u Date
是每个id的最新日期,…我也会陷入同样的陷阱。啊哈。谢谢你的澄清。