【发布时间】:2018-10-29 03:57:42
【问题描述】:
我正在尝试计算每个人 (sq_id) 的试验之间的时间量 (trialnumber)。我已经能够弄清楚如何计算试验之间的时间差 (time_gap),但我的输出包含所有这些不应该存在的重复行。
可以在here 找到我的数据子集。出于可重复性的目的,我在下面包含了数据集(称为export):
sq_id ageclass sex cohort year age grid trialnumber trialdate trialtime
6244 A F 2000 2005 5 AG 1 05/24/05 0:00
10212 A M 2006 2008 2 KL 1 05/04/08 6:13
10212 A M 2006 2010 4 KL 4 05/20/10 6:12
10212 A M 2006 2009 3 KL 2 06/10/09 6:14
10212 A M 2006 2009 3 KL 3 07/01/09 6:15
23052 J F 2017 2017 0 SU 2 08/02/17 11:00
23052 J F 2017 2017 0 SU 1 07/20/17 10:51
23080 J M 2017 2017 0 KL 2 07/29/17 10:20
23080 J M 2017 2017 0 KL 1 07/07/17 8:35
我做的第一件事是计算试验之间的时间,如下所示:
#adding time between trials to data
trialdate<-as.POSIXct(data$trialdate,format="%m/%d/%y")
data$datetime=as.POSIXct(paste(trialdate, data$trialtime),format= '%Y-%m-%d',usetz=FALSE)
#calculates time btw first trial and all other trials
timebtw <- data %>% group_by(sq_id) %>%
select(sq_id, trialnumber, datetime) %>%
mutate(time_gap = (datetime - nth(datetime, which.min((datetime)))), time_gap=time_gap/86400) #time_gap units are in seconds, changed to days
然后我将timebtw 数据集加入我的原始数据集(称为export):
new<-dplyr::left_join(export, timebtw, by = "sq_id")
我得到的输出如下所示:
> export
sq_id ageclass sex cohort year age grid trialnumber.x trialdate trialtime datetime time_gap trialnumber.y
6244 A F 2000 2005 5 AG 1 05/24/05 0:00 2005-05-24 0 secs 1
10212 A M 2006 2008 2 KL 1 05/04/08 6:13 2008-05-04 0 secs 1
10212 A M 2006 2008 2 KL 1 05/04/08 6:13 2008-05-04 746 secs 4
10212 A M 2006 2008 2 KL 1 05/04/08 6:13 2008-05-04 402 secs 2
10212 A M 2006 2008 2 KL 1 05/04/08 6:13 2008-05-04 423 secs 3
10212 A M 2006 2010 4 KL 4 05/20/10 6:12 2010-05-20 0 secs 1
10212 A M 2006 2010 4 KL 4 05/20/10 6:12 2010-05-20 746 secs 4
10212 A M 2006 2010 4 KL 4 05/20/10 6:12 2010-05-20 402 secs 2
10212 A M 2006 2010 4 KL 4 05/20/10 6:12 2010-05-20 423 secs 3
10212 A M 2006 2009 3 KL 2 06/10/09 6:14 2009-06-10 0 secs 1
10212 A M 2006 2009 3 KL 2 06/10/09 6:14 2009-06-10 746 secs 4
10212 A M 2006 2009 3 KL 2 06/10/09 6:14 2009-06-10 402 secs 2
10212 A M 2006 2009 3 KL 2 06/10/09 6:14 2009-06-10 423 secs 3
10212 A M 2006 2009 3 KL 3 07/01/09 6:15 2009-07-01 0 secs 1
10212 A M 2006 2009 3 KL 3 07/01/09 6:15 2009-07-01 746 secs 4
10212 A M 2006 2009 3 KL 3 07/01/09 6:15 2009-07-01 402 secs 2
10212 A M 2006 2009 3 KL 3 07/01/09 6:15 2009-07-01 423 secs 3
23052 J F 2017 2017 0 SU 2 08/02/17 11:00 2017-08-02 13 secs 2
23052 J F 2017 2017 0 SU 2 08/02/17 11:00 2017-08-02 0 secs 1
23052 J F 2017 2017 0 SU 1 07/20/17 10:51 2017-07-20 13 secs 2
23052 J F 2017 2017 0 SU 1 07/20/17 10:51 2017-07-20 0 secs 1
23080 J M 2017 2017 0 KL 2 07/29/17 10:20 2017-07-29 22 secs 2
23080 J M 2017 2017 0 KL 2 07/29/17 10:20 2017-07-29 0 secs 1
23080 J M 2017 2017 0 KL 1 07/07/17 8:35 2017-07-07 22 secs 2
23080 J M 2017 2017 0 KL 1 07/07/17 8:35 2017-07-07 0 secs 1
这是个问题。每个trialnumber 应该只有一个time_gap 值。
例如,对于sq_id 10212,输出应如下所示:
sq_id ageclass sex cohort year age grid trialnumber.x trialdate trialtime datetime time_gap trialnumber.y
10212 A M 2006 2008 2 KL 1 05/04/08 6:13 2008-05-04 0 secs 1
10212 A M 2006 2010 4 KL 4 05/20/10 6:12 2010-05-20 746 secs 4
10212 A M 2006 2009 3 KL 2 06/10/09 6:14 2009-06-10 402 secs 2
10212 A M 2006 2009 3 KL 3 07/01/09 6:15 2009-07-01 423 secs 3
我需要trialnumber.x 和trialnumber.y 列匹配,这样只有试验的行数(即sq_id 6244 将有1 行,sq_id 10212 4 行,@987654340 @ 23052 2 行,sq_id 23080 2 行)。
有谁知道我如何修改我的代码来获得这个输出?
【问题讨论】:
-
你加入 sq_id,它有 4 个 10212 的数据值和 4 个 timebw 值,加入时将返回 16 个值。您需要使用更多字段才能加入。你可以使用
left_join(df, timebtw, by = c("sq_id" = "sq_id", "trialnumber" = "trialnumber", "datetime" = "datetime")) -
@phiver 我从来不知道你可以加入多个领域!谢谢,效果很好。
-
@phiver 后续问题:如果我没有任何其他共同领域,我会怎么做? (即如果
timebtw仅包含sq_id和time_gap作为变量)? -
在那种情况下,@Aurèle 的回答是最好的。如果您有 timebtw 并且只有 sq_id 用于连接,那么您将始终需要解决一些问题。您可以使用 %in% 来检查它们是否是与其他表等匹配的值。在 SO 中搜索 semi_join ,这也应该带来一些其他答案。
-
@phiver 感谢您的建议。是的,@Aurèle 的解决方案对这个特定实例很有帮助(因为建议的解决方法),但它并没有以允许我将此解决方案转移到我面临的其他问题的方式回答我的原始问题。虽然我的 OP 是关于这个特定的数据集,但这是一个在我的编码中反复出现的问题。我会按照你的建议调查
semi_join。
标签: r datetime merge dplyr left-join