R - 基于重复虚拟变量调整起始变量与滞后 - 每行多次测量

问题描述

在我的数据中,如果虚拟变量重复,我想连续调整起始变量:

我有如下数据(我自己添加了 rcount 变量):

head(elevation_raw)

                start         duration       value     rcount
1 2021-02-20 12:41:00             [60]         [0]       1
2 2021-02-20 12:49:00       [60,20,37]     [0,0]       2
3 2021-02-20 12:57:00             [60]         [0]       3
4 2021-02-20 13:02:00             [60]         [0]       4
5 2021-02-20 13:09:00 [60,60,60] [0,0]       5
6 2021-02-20 14:19:00          [60,60]       [0,0]       6

您会看到测量的开始、测量的持续时间(测量持续多长时间,也指示测量的结束)和值(此处为海拔)。

您在第 1、5、6 行中看到,在一行中放置了多个测量值。例如,第 2 次测量在第 1 次开始 + 第一次持续时间之后开始。

我已经将数据放在带有 separate_rowsleft_join 的漂亮行中,但是“多重测量”行的开头是错误的。请注意,当 rcount 重复时,可以找到这些多个测量行:

durations <-  separate_rows(elevation_raw,duration,sep = ",",convert=T) %>%
  select( c(-value)) 
durations <- mutate(durations,rcount2 = as.numeric(rownames(durations)))

values <-  separate_rows(elevation_raw,value,convert=T) %>%
  select( -c(duration))
values <- mutate(values,rcount2 = as.numeric(rownames(values)))

elevation_raw <-left_join(durations,values,by=c('rcount2','rcount',"start")) 

#result:
head(elevation_raw)
# A tibble: 6 x 6
  start               duration   rcount rcount2 value
  <dttm>                 <int>   <dbl>   <dbl> <int>
1 2021-02-20 12:41:00       60   1       1     0
2 2021-02-20 12:49:00       60   2       2     0       #"multiple measurement" row,see rcount
3 2021-02-20 12:49:00       20   2       3     0       #"multiple measurement" row
4 2021-02-20 12:49:00       37   2       4     0       #"multiple measurement" row
5 2021-02-20 12:57:00       60   3       5     0
6 2021-02-20 13:02:00       60   4       6     0

当然,我想添加一个带有真正开始的列,因为现在“多重测量”行的开始是不正确的。我尝试了以下方法

elevation_raw<- mutate(elevation_raw,real_start=ifelse(rcount==dplyr::lag(rcount),dplyr::lag(elevation_raw$real_start)+dplyr::lag(elevation_raw$duration),elevation_raw$start) )

如果 rcount 是重复的(使用 (rcount==lag(rcount) ),那么实际行的真正开始是前一行的真正开始 + 前一行的持续时间。其他与正常启动时相同。 当然,这种方法不起作用:我不能使用我现在正在构建的列来构建列(尽管我认为如果第一行不是多重测量行,则 real_start 将是正常的开始,并且它可能会起作用,因为我们会有第一个值开始......)。 (如果我使用正常的起始列,它对于多行的第二次测量是正确的。)

也许我应该以不同的方式来处理它,即使用应用函数?感谢您的帮助,如果您对如何让我的问题更清楚有任何建议,请告诉我。

解决方法

喜欢吗?

library(data.table)
library(stringr)
# Sample data
DT <- fread("
                start         duration       value     rcount
2021-02-20T12:41:00             [60]         [0]       1
2021-02-20T12:49:00       [60,20,37]     [0,0]       2
2021-02-20T12:57:00             [60]         [0]       3
2021-02-20T13:02:00             [60]         [0]       4
2021-02-20T13:09:00 [60,60,60] [0,0]       5
2021-02-20T14:19:00          [60,60]       [0,0]       6")
DT[,start := as.POSIXct(start,format = "%Y-%m-%dT%H:%M:%S")]
# maximum number of duration/values
ncols <- length(tstrsplit(DT$duration,","))
# split the durarion and value columns
DT[,paste0("duration",1:ncols) := lapply(transpose(str_extract_all(duration,"\\d+")),as.numeric)]
DT[,paste0("value",1:ncols) := lapply(transpose(str_extract_all(value,as.numeric)]
# Driop the original value and durarion columns
DT[,`:=`(duration = NULL,value = NULL)]
answer <- melt(DT,measure.vars = patterns(duration = "^duration[0-9]",value = "^value[0-9]"),na.rm = TRUE)
# Order
setkey(answer,rcount,variable)
# start addition = cumulative sum of durations
answer[,start_new := start + (cumsum(duration) - duration[1]),by = .(rcount)][]
#                  start rcount variable duration value           start_new
# 1: 2021-02-20 12:41:00      1        1       60     0 2021-02-20 12:41:00
# 2: 2021-02-20 12:49:00      2        1       60     0 2021-02-20 12:49:00
# 3: 2021-02-20 12:49:00      2        2       20     0 2021-02-20 12:49:20
# 4: 2021-02-20 12:49:00      2        3       37     0 2021-02-20 12:49:57
# 5: 2021-02-20 12:57:00      3        1       60     0 2021-02-20 12:57:00
# 6: 2021-02-20 13:02:00      4        1       60     0 2021-02-20 13:02:00
# 7: 2021-02-20 13:09:00      5        1       60     0 2021-02-20 13:09:00
# 8: 2021-02-20 13:09:00      5        2       60     0 2021-02-20 13:10:00
# 9: 2021-02-20 13:09:00      5        3       60     0 2021-02-20 13:11:00
#10: 2021-02-20 13:09:00      5        4       60     0 2021-02-20 13:12:00
#11: 2021-02-20 13:09:00      5        5       60     0 2021-02-20 13:13:00
#12: 2021-02-20 14:19:00      6        1       60     0 2021-02-20 14:19:00
#13: 2021-02-20 14:19:00      6        2       60     0 2021-02-20 14:20:00