创建一个循环以在同一行中记录下一个记录时间和日期(基于唯一 ID)
Posted
技术标签:
【中文标题】创建一个循环以在同一行中记录下一个记录时间和日期(基于唯一 ID)【英文标题】:Create a loop to record next record time and date (based on unique id) in same row 【发布时间】:2022-01-21 01:51:27 【问题描述】:我正在尝试创建一个循环和一个 if/else 语句来拉下一行的时间以将其记录为超时。如果没有下一行(即没有汽车 id#)作为结束/退出返回。 Data and envisioned output
这是我的代码,但它根本不起作用,可能没有正确掌握基础知识。
for(i in 1:dim(df2)[1])
if(df2$car.id[i] == df2$car.id[i +1])
return$timein[i+1]
else
print("end")
)
【问题讨论】:
欢迎来到 Stack Overflow。请不要使用数据图像,因为没有大量不必要的努力就无法使用它们。 For multiple reasons。如果你的问题是可重复的,你更有可能得到积极的回应。 See Stack Overflow question guidance 粘贴dput(df2)
的输出或数据框的样本。
【参考方案1】:
下面有几个注释,但先试试这个:
df2$Timeout <- ave(df2$Timein, df2$car.id, FUN = function(z) c(z[-1], NA))
上面的代码返回df2$Timein
的下一个值每个df2$car.id
,当下一行是不同的car.id
时正确重置。顺序很重要,所以如果您需要对Timein
进行排序,那么您应该在调用ave(.)
之前对其进行排序。 (这将正确处理car.id
出现故障甚至混杂。)
您的(图像)代码存在问题。如果上述方法不起作用,您需要澄清这些要点。
nrow(df2)
是比dim(df2)[1]
更规范的方法。
我推荐for (i in seq_len(nrow(df2)))
,而不是nrow(.)
,因为它至少在一个极端情况下表现更好。
您的[i+1]
索引将超出索引限制并返回 NA,这最终将与missing value where TRUE/FALSE needed
出错。
return$timein[i+1]
似乎是错误的,除非您有一个命名列表或data.frame
对象,即return
;我不鼓励这样做,因为它可能(被人们)与基本 R 原语(函数)return(.)
混淆。如果它不是一个对象,那么你就用错了,坦率地说我不知道它应该是什么,因为这里的 for 循环似乎没有必要。
您的预期输出并不完全清楚,但我猜您想要时间戳或文字 "End"
。后者会破坏你的时间戳,将它们从POSIXt
-class 对象转换为字符串。一般来说,框架中的一列不能混合类。
【讨论】:
【参考方案2】:尝试使用dplyr
。使用玩具数据。
library(dplyr)
dat %>% group_by( car.id ) %>%
mutate( Timeout=lead(as.character(Timein), default="END") ) %>% ungroup
# A tibble: 10 x 4
car.id car.type Timein Timeout
<dbl> <dbl> <dttm> <chr>
1 14359825 1 2021-12-18 17:28:58 2021-12-18 17:33:58
2 14359825 1 2021-12-18 17:33:58 2021-12-18 18:03:58
3 14359825 1 2021-12-18 18:03:58 2021-12-18 18:08:58
4 14359825 1 2021-12-18 18:08:58 2021-12-18 18:13:58
5 14359825 1 2021-12-18 18:13:58 END
6 243095743 2 2021-12-18 18:30:38 2021-12-18 18:37:18
7 243095743 2 2021-12-18 18:37:18 2021-12-18 19:17:18
8 243095743 2 2021-12-18 19:17:18 2021-12-18 19:23:58
9 243095743 2 2021-12-18 19:23:58 2021-12-18 19:30:38
10 243095743 2 2021-12-18 19:30:38 END
如果您想要一个仅限日期的 Timeout
列,您可以随时重铸
as.POSIXct( dat$Timeout, format="%F %T" )
[1] "2021-12-18 17:33:58 CET" "2021-12-18 18:03:58 CET"
[3] "2021-12-18 18:08:58 CET" "2021-12-18 18:13:58 CET"
[5] NA "2021-12-18 18:37:18 CET"
[7] "2021-12-18 19:17:18 CET" "2021-12-18 19:23:58 CET"
[9] "2021-12-18 19:30:38 CET" NA
或直接使用
dat %>% group_by( car.id ) %>% mutate( Timeout=lead( Timein ) )
数据
dat <- structure(list(car.id = c(14359825, 14359825, 14359825, 14359825,
14359825, 243095743, 243095743, 243095743, 243095743, 243095743
), car.type = c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2), Timein = structure(c(1639844938.6685,
1639845238.6685, 1639847038.6685, 1639847338.6685, 1639847638.6685,
1639848638.6685, 1639849038.6685, 1639851438.6685, 1639851838.6685,
1639852238.6685), class = c("POSIXct", "POSIXt"))), row.names = c(NA,
10L), class = "data.frame")
【讨论】:
仅供参考,如果Timein
是 POSIXt
,那么使用此解决方案,Timout
将是 character
。如果Timein
是开头的字符串向量,则不是问题。
@r2evans 是的,我决定默默地转换为字符以匹配所需的输出。但你可能有权在某处提及该演员......以上是关于创建一个循环以在同一行中记录下一个记录时间和日期(基于唯一 ID)的主要内容,如果未能解决你的问题,请参考以下文章