динамически сравнивать столбцы в data.table в R - PullRequest
0 голосов
/ 16 июня 2020

У меня есть таблица data.table, в которой есть несколько столбцов даты. Это столбцы даты K, при этом K изменяется. Я вычислил разницу во времени между столбцами:

K <- numberOfYears
dateCols = c("fromdatenext", paste0("fromdate" , 1:K))

# create formulas dynamically 
all_operations = lapply(seq_len(length(dateCols) - 1), function(i){
  as.formula(paste("~difftime(", dateCols[i + 1], ",", dateCols[i],", units = c('weeks'))"))
})

df %>%
  mutate_(.dots = setNames(all_operations, paste0("Diff", seq_len(length(dateCols) - 1))))

и получил что-то вроде:

  fromdatenext  fromdate1  fromdate2  fromdate3  fromdate4           Diff1           Diff2           Diff3           Diff4
1   2018-01-01 2017-01-01 2016-01-01 2015-01-01 2014-01-01 -52.14286 weeks -52.28571 weeks -52.14286 weeks -52.14286 weeks
2   2018-10-01 2017-10-01 2016-10-01 2015-10-01 2014-10-01 -52.14286 weeks -52.14286 weeks -52.28571 weeks -53.14286 weeks
3   2018-09-08 2017-09-08 2016-09-08 2015-09-08 2014-09-08 -52.14286 weeks -52.14286 weeks -52.28571 weeks -52.14286 weeks
4   2018-09-22 2017-09-22 2016-09-22 2015-09-22 2014-09-22 -52.14286 weeks -52.14286 weeks -52.28571 weeks -52.14286 weeks
5   2018-05-01 2017-05-01 2016-05-01 2015-05-01 2014-05-01 -52.14286 weeks -52.14286 weeks -52.28571 weeks -52.14286 weeks
6   2018-01-01 2017-01-01 2016-01-01 2015-01-01 2014-01-01 -50.14286 weeks -52.28571 weeks -52.14286 weeks -52.14286 weeks

Теперь мне нужно удалить все строки, которые не имеют равного временного интервала. Как это можно сделать динамически, чтобы при K он все еще работал?

, поэтому желаемый результат будет:

  fromdatenext  fromdate1  fromdate2  fromdate3  fromdate4           Diff1           Diff2           Diff3           Diff4
1   2018-01-01 2017-01-01 2016-01-01 2015-01-01 2014-01-01 -52.14286 weeks -52.28571 weeks -52.14286 weeks -52.14286 weeks
3   2018-09-08 2017-09-08 2016-09-08 2015-09-08 2014-09-08 -52.14286 weeks -52.14286 weeks -52.28571 weeks -52.14286 weeks
4   2018-09-22 2017-09-22 2016-09-22 2015-09-22 2014-09-22 -52.14286 weeks -52.14286 weeks -52.28571 weeks -52.14286 weeks
5   2018-05-01 2017-05-01 2016-05-01 2015-05-01 2014-05-01 -52.14286 weeks -52.14286 weeks -52.28571 weeks -52.14286 weeks

1 Ответ

0 голосов
/ 16 июня 2020

В целом, я думаю, что этот тип данных (переменное количество идентично структурированных / предназначенных столбцов) может лучше работать в «длинном» формате, и в этом случае я предлагаю ваш метод:

library(dplyr)
library(tidyr) # pivot_*
dat2 <- dat %>%
  mutate(rn = row_number()) %>%
  pivot_longer(matches("fromdate[0-9]+"), names_to = "num", values_to = "fromdate") %>%
  group_by(rn) %>%
  mutate(
    fromdatenext = as.Date(fromdatenext),
    fromdate = as.Date(fromdate),
    num = gsub("\\D", "", num),
    Diff = `units<-`(diff(c(first(fromdatenext), fromdate)), "weeks")
  ) %>%
  ungroup()
dat2
# # A tibble: 24 x 5
#    fromdatenext    rn num   fromdate   Diff          
#    <date>       <int> <chr> <date>     <drtn>        
#  1 2018-01-01       1 1     2017-01-01 -52.1429 weeks
#  2 2018-01-01       1 2     2016-01-01 -52.2857 weeks
#  3 2018-01-01       1 3     2015-01-01 -52.1429 weeks
#  4 2018-01-01       1 4     2014-01-01 -52.1429 weeks
#  5 2018-10-01       2 1     2017-10-01 -52.1429 weeks
#  6 2018-10-01       2 2     2016-10-01 -52.1429 weeks
#  7 2018-10-01       2 3     2015-10-01 -52.2857 weeks
#  8 2018-10-01       2 4     2014-10-01 -52.1429 weeks
#  9 2018-09-08       3 1     2017-09-08 -52.1429 weeks
# 10 2018-09-08       3 2     2016-09-08 -52.1429 weeks
# # ... with 14 more rows

Однако, если вы хотите / нуждаетесь в них в более широком формате, мы можем просто повторно развернуть его обратно на широкий:

dat2 %>%
  pivot_wider(
    id_cols = rn:fromdatenext,
    names_from = num,
    values_from = c(fromdate, Diff),
    names_sep = ""
  )
# # A tibble: 6 x 10
#      rn fromdatenext fromdate1  fromdate2  fromdate3  fromdate4  Diff1          Diff2          Diff3          Diff4         
#   <int> <date>       <date>     <date>     <date>     <date>     <drtn>         <drtn>         <drtn>         <drtn>        
# 1     1 2018-01-01   2017-01-01 2016-01-01 2015-01-01 2014-01-01 -52.1429 weeks -52.2857 weeks -52.1429 weeks -52.1429 weeks
# 2     2 2018-10-01   2017-10-01 2016-10-01 2015-10-01 2014-10-01 -52.1429 weeks -52.1429 weeks -52.2857 weeks -52.1429 weeks
# 3     3 2018-09-08   2017-09-08 2016-09-08 2015-09-08 2014-09-08 -52.1429 weeks -52.1429 weeks -52.2857 weeks -52.1429 weeks
# 4     4 2018-09-22   2017-09-22 2016-09-22 2015-09-22 2014-09-22 -52.1429 weeks -52.1429 weeks -52.2857 weeks -52.1429 weeks
# 5     5 2018-05-01   2017-05-01 2016-05-01 2015-05-01 2014-05-01 -52.1429 weeks -52.1429 weeks -52.2857 weeks -52.1429 weeks
# 6     6 2018-01-01   2017-01-01 2016-01-01 2015-01-01 2014-01-01 -52.1429 weeks -52.2857 weeks -52.1429 weeks -52.1429 weeks

Данные:

dat <- read.table(header = TRUE, text = "
fromdatenext  fromdate1  fromdate2  fromdate3  fromdate4
  2018-01-01 2017-01-01 2016-01-01 2015-01-01 2014-01-01
  2018-10-01 2017-10-01 2016-10-01 2015-10-01 2014-10-01
  2018-09-08 2017-09-08 2016-09-08 2015-09-08 2014-09-08
  2018-09-22 2017-09-22 2016-09-22 2015-09-22 2014-09-22
  2018-05-01 2017-05-01 2016-05-01 2015-05-01 2014-05-01
  2018-01-01 2017-01-01 2016-01-01 2015-01-01 2014-01-01")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...