обединете множество колони за дата и час в колона за дата и час R

За данните по-долу:

> dt
         date   event1   event2   event3
1: 2016-04-27 10:25:15 11:05:45 13:00:09
2: 2016-04-27 10:25:15 11:05:45 13:00:09
3: 2016-04-27 10:25:15 11:05:45 13:00:09
4: 2016-04-27 10:25:15 11:05:45 13:00:09
5: 2016-04-27 10:25:15 11:05:45 13:00:09

Бих искал да обединя date с всяка от колоните за събития, за да направя колоните за време на събитието във формат datetime. Желан резултат:

dt$event1 = as.POSIXct(paste(dt$date, dt$event1), format="%Y-%m-%d %H:%M:%S")
dt$event2 = as.POSIXct(paste(dt$date, dt$event2), format="%Y-%m-%d %H:%M:%S")
dt$event3 = as.POSIXct(paste(dt$date, dt$event3), format="%Y-%m-%d %H:%M:%S")
dt$date = NULL

  > dt
                event1              event2              event3
1: 2016-04-27 10:25:15 2016-04-27 11:05:45 2016-04-27 13:00:09
2: 2016-04-27 10:25:15 2016-04-27 11:05:45 2016-04-27 13:00:09
3: 2016-04-27 10:25:15 2016-04-27 11:05:45 2016-04-27 13:00:09
4: 2016-04-27 10:25:15 2016-04-27 11:05:45 2016-04-27 13:00:09
5: 2016-04-27 10:25:15 2016-04-27 11:05:45 2016-04-27 13:00:09

Тъй като имам доста голям набор от данни с >300 000 реда и >20 колони за време на събитие, кой е най-ефективният начин да направя това наведнъж за всички колони за време на събитие в dplyr или data.table, моля?

Примерни данни:

dt = data.table(date = rep(as.POSIXct("2016-04-27"),5), event1 = rep("10:25:15",5), event2 = rep("11:05:45",5), event3 = rep("13:00:09",5))

person pyne    schedule 14.03.2019    source източник
comment
Можете ли да предоставите желания резултат?   -  person George    schedule 14.03.2019
comment
Не съм много загрижен за дублирането. В примера event1 може просто да бъде заменено, вместо да генерира event1_datetime - ще актуализира въпроса, за да стане по-ясен   -  person pyne    schedule 14.03.2019


Отговори (3)


Можем да използваме mutate_at за добавяне на нови колони

library(dplyr)

dt %>%
  mutate_at(vars(starts_with("event")), funs(as.POSIXct(paste0(date, .)))) %>%
  select(-date)

#               event1              event2              event3
#1 2016-04-27 10:25:15 2016-04-27 11:05:45 2016-04-27 13:00:09
#2 2016-04-27 10:25:15 2016-04-27 11:05:45 2016-04-27 13:00:09
#3 2016-04-27 10:25:15 2016-04-27 11:05:45 2016-04-27 13:00:09
#4 2016-04-27 10:25:15 2016-04-27 11:05:45 2016-04-27 13:00:09
#5 2016-04-27 10:25:15 2016-04-27 11:05:45 2016-04-27 13:00:09
person Ronak Shah    schedule 14.03.2019
comment
Благодаря ти! и благодаря, че актуализирахте отговора си, след като въпросът ми беше редактиран - наистина го оценявам! - person pyne; 14.03.2019

Не съм сигурен какво общо има това със сливането; не е ли това просто

dt[, event1_datetime := as.POSIXct(paste(date, event1))]
#         date   event1   event2   event3     event1_datetime
#1: 2016-04-27 10:25:15 11:05:45 13:00:09 2016-04-27 10:25:15
#2: 2016-04-27 10:25:15 11:05:45 13:00:09 2016-04-27 10:25:15
#3: 2016-04-27 10:25:15 11:05:45 13:00:09 2016-04-27 10:25:15
#4: 2016-04-27 10:25:15 11:05:45 13:00:09 2016-04-27 10:25:15
#5: 2016-04-27 10:25:15 11:05:45 13:00:09 2016-04-27 10:25:15

Актуализация

Колкото и да си струва, ето data.table решение, използващо melt и dcast

dt[, n := 1:.N]
dt <- melt(dt[, n := 1:.N], id.vars = c("date", "n"), value.name = "time")
dt[, datetime := as.POSIXct(paste(date, time))]
dt <- dcast(dt, date + n ~ variable, value.var = c("time", "datetime"))
dt[, n := NULL]
#         date time_event1 time_event2 time_event3     datetime_event1
#1: 2016-04-27    10:25:15    11:05:45    13:00:09 2016-04-27 10:25:15
#2: 2016-04-27    10:25:15    11:05:45    13:00:09 2016-04-27 10:25:15
#3: 2016-04-27    10:25:15    11:05:45    13:00:09 2016-04-27 10:25:15
#4: 2016-04-27    10:25:15    11:05:45    13:00:09 2016-04-27 10:25:15
#5: 2016-04-27    10:25:15    11:05:45    13:00:09 2016-04-27 10:25:15
#       datetime_event2     datetime_event3
#1: 2016-04-27 11:05:45 2016-04-27 13:00:09
#2: 2016-04-27 11:05:45 2016-04-27 13:00:09
#3: 2016-04-27 11:05:45 2016-04-27 13:00:09
#4: 2016-04-27 11:05:45 2016-04-27 13:00:09
#5: 2016-04-27 11:05:45 2016-04-27 13:00:09

Или всичко наведнъж

dcast(melt(dt[, n := 1:.N], id.vars = c("date", "n"), value.name = "time")[,
    datetime := as.POSIXct(paste(date, time))], 
    date + n ~ variable, value.var = c("time", "datetime"))[,
    n := NULL][]
person Maurits Evers    schedule 14.03.2019
comment
да, но бих искал да направя това за всички колони за събития (event1, event2, event3 и т.н., всички наведнъж. - person pyne; 14.03.2019
comment
ААА разбирам; добре, в такъв случай преоформянето от широк на дълъг, след това добавяне на датата и преоформянето обратно на широк ще работи. Ще публикувам актуализация... - person Maurits Evers; 14.03.2019
comment
@pyne За това, което (все още) си струва, добавих data.table решение, което отчита произволен брой колони за събития. - person Maurits Evers; 14.03.2019
comment
Благодаря ти, @Maurits Evers - обикновено намирам data.table за по-бърз, толкова е страхотно, че имам опцията! - person pyne; 14.03.2019

Възможен подход с използване на .SDcols:

cols <- paste0(grep("^event", names(dt), value=TRUE), "_datetime")
dt[, (cols) := 
    lapply(.SD, function(x) as.POSIXct(paste(date, x), format="%Y-%m-%d %H:%M:%S")), 
        .SDcols=event1:event3]

изход:

         date   event1   event2   event3     event1_datetime     event2_datetime     event3_datetime
1: 2016-04-27 10:25:15 11:05:45 13:00:09 2016-04-27 10:25:15 2016-04-27 11:05:45 2016-04-27 13:00:09
2: 2016-04-27 10:25:15 11:05:45 13:00:09 2016-04-27 10:25:15 2016-04-27 11:05:45 2016-04-27 13:00:09
3: 2016-04-27 10:25:15 11:05:45 13:00:09 2016-04-27 10:25:15 2016-04-27 11:05:45 2016-04-27 13:00:09
4: 2016-04-27 10:25:15 11:05:45 13:00:09 2016-04-27 10:25:15 2016-04-27 11:05:45 2016-04-27 13:00:09
5: 2016-04-27 10:25:15 11:05:45 13:00:09 2016-04-27 10:25:15 2016-04-27 11:05:45 2016-04-27 13:00:09

данни:

library(data.table)
dt <- fread("date   event1   event2   event3
2016-04-27 10:25:15 11:05:45 13:00:09
2016-04-27 10:25:15 11:05:45 13:00:09
2016-04-27 10:25:15 11:05:45 13:00:09
2016-04-27 10:25:15 11:05:45 13:00:09
2016-04-27 10:25:15 11:05:45 13:00:09")
person chinsoon12    schedule 14.03.2019