首页 > 解决方案 > R - 基于重复虚拟变量调整起始变量,带有 lag() - 每行多次测量

问题描述

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

我有以下数据(我自己添加了 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,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,60,60] [0,0,0,0,0]       5
6 2021-02-20 14:19:00          [60,60]       [0,0]       6

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

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

separate_rows我已经用and将数据放在了很好的行中left_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, sep = ",", 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 将是正常的开始,并且它可能会起作用,因为我们将有一个开始的第一个值......)。(如果我使用正常的起始列,它对于多行的第二次测量是正确的。)

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

标签: rdplyrapplydata-cleaningtapply

解决方案


像这样?

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,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,60,60] [0,0,0,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, "\\d+")), as.numeric)]
# For decimal values, replace the line above with the following line
# DT[, paste0("value", 1:ncols) := lapply(transpose(str_extract_all(value, "[0-9]\\d*(\\.\\d+)?")), 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

推荐阅读