gpt4 book ai didi

r - 创建一个函数来替换计算 session 的列中的 NA

转载 作者:行者123 更新时间:2023-12-01 22:20:28 24 4
gpt4 key购买 nike

我有一个数据框,看起来像下面的示例数据框:

#sample data frame
clientId actual_time session
1 A 2016-11-01 00:00:00 1
2 A 2016-11-01 00:05:00 1
3 A 2016-11-01 00:35:01 2
4 A 2016-11-01 00:40:00 NA
5 A 2016-11-01 01:10:01 NA
6 B 2016-11-01 01:00:00 1
7 B 2016-11-01 01:05:00 1
8 B 2016-11-01 01:30:00 1
9 B 2016-11-01 01:40:00 1
10 B 2016-11-01 01:50:00 NA
11 C 2016-11-01 02:00:00 NA
12 C 2016-11-01 02:35:00 NA
13 C 2016-11-01 04:35:00 NA

我想用定义为逻辑的值填充“session”列中的 NAs:

  • 对于相同的“clientId”,如果两个后续行之间的时间差 >= 30 分钟,则较新的行将在一个新 session 中(等于旧行的 session 加 1);如果两个后续行之间的时间差小于 30 分钟,则这两行都在具有相同 session 号的同一 session 中。
  • session 号是从1开始的累计数,即对于一个新的clientId, session 号从1开始。

NA填满后,数据框会是这样的:

#sample data frame (result)
clientId actual_time session
1 A 2016-11-01 00:00:00 1
2 A 2016-11-01 00:05:00 1
3 A 2016-11-01 00:35:01 2
4 A 2016-11-01 00:40:00 2
5 A 2016-11-01 01:10:00 3
6 B 2016-11-01 01:00:00 1
7 B 2016-11-01 01:05:00 1
8 B 2016-11-01 01:30:00 1
9 B 2016-11-01 01:40:00 1
10 B 2016-11-01 01:50:00 1
11 C 2016-11-01 02:00:00 1
12 C 2016-11-01 02:35:00 2
13 C 2016-11-01 04:35:00 3

我试过:

df<-data.frame(clientId=c(rep('A',5),rep('B',5),rep('C',3)),
actual_time=as.POSIXct(c("2016-11-01 00:00:00","2016-11-01 00:05:00","2016-11-01 00:35:01","2016-11-01 00:40:00","2016-11-01 01:10:01",
"2016-11-01 01:00:00","2016-11-01 01:05:00","2016-11-01 01:30:00","2016-11-01 01:40:00","2016-11-01 01:50:00",
"2016-11-01 02:00:00","2016-11-01 02:35:00","2016-11-01 04:35:00")),
session=c(1,1,2,NA,NA,1,1,1,1,NA,NA,NA,NA))

my_session<- function(df){

for (i in 2:(dim(df)[1])){
if(is.na(df$session[i])){
if (df$clientId[i]==df$clientId[i-1]){
if(as.numeric(difftime(df$actual_time[i],
df$actual_time[i-1], Asia/Taipei,units = "mins"))>30){
df$session[i]<- df$session[i-1]+1
}else{df$session[i]<- df$session[i-1]}
}else{df$session[i]<- 1}
}
}

return(df)
}

df2<-my_session(df)

该功能确实有效。但是,它非常慢,因为我的实际数据帧有 800 万行(一个 4G csv 文件)。

我认为运行 for 循环时会消耗时间。有没有一种方法可以编写一个无需 for 循环即可填充 NA 的函数?

最佳答案

我将提出一个 data.table 方法,它应该比您现有的函数扩展得更好。

library(data.table)
DT <- as.data.table(df) # or setDT(df)
DT[, session := cumsum(difftime(actual_time, shift(actual_time,
fill = min(actual_time)), units = "mins") > 30) +1L,
by = clientId]

它的作用:它按 clientId 组计算两个 actual_time 相差超过 30 分钟的累计次数。当然,你必须确保数据是按实际时间排序的。

生成的表格如下所示:

 #   clientId         actual_time session
#1: A 2016-11-01 00:00:00 1
#2: A 2016-11-01 00:05:00 1
#3: A 2016-11-01 00:35:01 2
#4: A 2016-11-01 00:40:00 2
#5: A 2016-11-01 01:10:01 3
#6: B 2016-11-01 01:00:00 1
#7: B 2016-11-01 01:05:00 1
#8: B 2016-11-01 01:30:00 1
#9: B 2016-11-01 01:40:00 1
#10: B 2016-11-01 01:50:00 1
#11: C 2016-11-01 02:00:00 1
#12: C 2016-11-01 02:35:00 2
#13: C 2016-11-01 04:35:00 3

关于r - 创建一个函数来替换计算 session 的列中的 NA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40483408/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com