Связать строки на основе условий с data.table - PullRequest
1 голос
/ 24 марта 2019

У меня есть 2 таблицы данных, которые я хотел бы объединить, связав строки.Ниже приведены значения данных:

    >dput(x)
    structure(list(NN = c("test", "test", "test", "test", "test"), 
    gpn = c("gas", "gas", "gas", "gas", "gas"), sitename = c("agip", 
    "agip", "agip", "agip", "agip"), code = c("F123", "F123", 
    "F123", "F123", "F123"), Brand = c("bp", "shell", "ionic", 
    "meta", "robo"), starttime = structure(c(1533097609, 1533118867, 
    1533183999, 1533270359, 1533356437), class = c("POSIXct", 
    "POSIXt"), tzone = ""), endtime = structure(c(1533118867, 
    1533183999, 1533270359, 1533356437, 1533443068), class = c("POSIXct", 
    "POSIXt"), tzone = ""), price = c(1.592, 1.592, 1.598, 1.598, 
    1.598), otherprice = c(1.998, 2.11, 2.114, 2.134, 1.989)), .Names = c("NN", 
"gpn", "sitename", "code", "Brand", "starttime", "endtime", "price", 
"otherprice"), row.names = c(NA, -5L), class = c("data.table", 
"data.frame"), .internal.selfref = <pointer: 0x00000000025c0788>)



>dput(y)

structure(list(NN = c("test", "test", "test", "test", "test"), 
gpn = c("gas", "gas", "gas", "gas", "gas"), sitename = c("agip", 
"agip", "agip", "agip", "agip"), code = c("F123", "F123", 
"F123", "F123", "F123"), Brand = c("dino", "dino", "dino", 
"dino", "dino"), otherprice = c(1.987, 2.456, 3.456, 1.989, 
1.99), starttime = structure(c(1533097399, 1533118999, 1533184999, 
1533271999, 1533359357), tzone = "", class = c("POSIXct", 
"POSIXt")), endtime = structure(c(1533118100, 1533182999, 
1533270000, 1533356000, 1533443000), class = c("POSIXct", 
"POSIXt"), tzone = "")), .Names = c("NN", "gpn", "sitename", 

"код", "бренд", "другая цена", "время начала", "время окончания"), класс = c ("data.table", "data.frame)"), .internal.selfref =)

Я бы хотел связать строки от y до x так, чтобы совпадало следующее:

псевдокод:

If (NN,код из 'x' соответствует NN, код из 'y') & 'x $ starttime' <'y $ starttime' & 'x $ endtime'> 'y $ endtime'

Тогда получите NN, код,бренд, цена от 'y' и результирующий кадр станет:

NN    gpn    sitename   code   Brand        starttime          endtime price otherprice
 test gas     agip      F123    bp    01/08/2018 05:26 01/08/2018 11:21 1.592      1.998
 test gas     agip      F123   shell 01/08/2018 11:21 02/08/2018 05:26 1.592      2.110
 test gas     agip      F123   Ionic 02/08/2018 05:26 03/08/2018 05:25 1.598      2.114
 test gas     agip      F123    meta 03/08/2018 05:25 04/08/2018 05:20 1.598      2.134
 test gas     agip      F123    robo 04/08/2018 05:20 05/08/2018 05:24 1.598      1.989
 test gas     agip      F123    dino 01/08/2018 05:26 01/08/2018 11:21 1.592      1.987
 test gas     agip      F123    dino 01/08/2018 11:21 02/08/2018 05:26 1.592      2.456
 test gas     agip      F123    dino 02/08/2018 05:26 03/08/2018 05:25 1.598      3.456
 test gas     agip      F123    dino 03/08/2018 05:25 04/08/2018 05:20 1.598      1.989
test gas     agip       F123    dino 04/08/2018 05:20 05/08/2018 05:24 1.598      1.990

Я проверил InsertRow и rbind, но ни один не работает.

Есть идеи?

Спасибо.

Ответы [ 2 ]

1 голос
/ 30 марта 2019

Чтобы объединить наборы данных, кажется, что хорошим решением является просто rbind наборов данных при использовании merge, чтобы обусловить наборы данных ограничениями времени начала / окончания. В приведенном ниже примере функция rbind вкладывает условие merge для дат начала и окончания:

library('data.table')
z <- rbind(
  x = x,
  y = merge(x[, .(code, starttime.x = starttime, endtime.x = endtime, price)], y, 
            by = 'code',
            allow.cartesian = TRUE,
            all.x = TRUE)[starttime.x < starttime & endtime.x > endtime,
                          .SD,
                          .SDcols = c(paste0(names(y)), 'price')])
z

Выход:

     NN gpn sitename code Brand           starttime             endtime price otherprice
1: test gas     agip F123    bp 2018-08-01 00:26:49 2018-08-01 06:21:07 1.592      1.998
2: test gas     agip F123 shell 2018-08-01 06:21:07 2018-08-02 00:26:39 1.592      2.110
3: test gas     agip F123 ionic 2018-08-02 00:26:39 2018-08-03 00:25:59 1.598      2.114
4: test gas     agip F123  meta 2018-08-03 00:25:59 2018-08-04 00:20:37 1.598      2.134
5: test gas     agip F123  robo 2018-08-04 00:20:37 2018-08-05 00:24:28 1.598      1.989
6: test gas     agip F123  dino 2018-08-01 06:23:19 2018-08-02 00:09:59 1.592      2.456
7: test gas     agip F123  dino 2018-08-02 00:43:19 2018-08-03 00:20:00 1.598      3.456
8: test gas     agip F123  dino 2018-08-03 00:53:19 2018-08-04 00:13:20 1.598      1.989
9: test gas     agip F123  dino 2018-08-04 01:09:17 2018-08-05 00:23:20 1.598      1.990
1 голос
/ 24 марта 2019

Мы можем объединить, используя dplyr, однако есть несколько предостережений из-за предоставленной структуры.Из dput() мы видим, что y не имеет переменной sitename, starttime и starttime являются факторами и должны быть преобразованы в posixct, а переменная brand в y имеет нижний регистр"b", но Brand в x имеет прописную букву "B".

В соответствии с этими наблюдениями мы можем сделать следующее:

# Change time to posixct to be consistent with x. 
# NOTE: You may have to adjust the time zone
y$starttime = as.POSIXct(y$starttime)
y$endtime = as.POSIXct(y$endtime)

# Chance 'brand' to 'Brand'
colnames(y)[colnames(y)=="brand"] = "Brand"

# Change other variabes as mentioned in commen
y$otherprice = y$price
y$price = x$price
y$sitename = x$sitename

Мы можем создать подмножествакоторые удовлетворяют упомянутым критериям (т.е. выбирают подмножество x и y, где x$starttime < y$starttime и x$endtime > y$endtime)

# Create subsets which match criteria
x.subset = subset(x, subset = x$starttime < y$starttime & x$endtime > y$endtime)
y.subset = subset(y, subset = x$starttime < y$starttime & x$endtime > y$endtime)

Теперь мы можем связать подмножества

# Row bind
library(dplyr)
z = dplyr::bind_rows(x.subset, y.subset)
> z
      NN gpn sitename code Brand           starttime             endtime price otherprice
 1: test gas     agip F123    bp 2018-08-01 00:26:49 2018-08-01 06:21:07 1.592      1.998
 2: test gas     agip F123 shell 2018-08-01 06:21:07 2018-08-02 00:26:39 1.592      2.110
 3: test gas     agip F123 ionic 2018-08-02 00:26:39 2018-08-03 00:25:59 1.598      2.114
 4: test gas     agip F123  meta 2018-08-03 00:25:59 2018-08-04 00:20:37 1.598      2.134
 5: test gas     agip F123  robo 2018-08-04 00:20:37 2018-08-05 00:24:28 1.598      1.989
 6: test gas     agip F123  dino 2018-08-01 00:33:19 2018-08-01 06:08:20 1.592      1.987
 7: test gas     agip F123  dino 2018-08-01 06:23:19 2018-08-02 00:09:59 1.592      2.456
 8: test gas     agip F123  dino 2018-08-02 00:43:19 2018-08-03 00:20:00 1.598      3.456
 9: test gas     agip F123  dino 2018-08-03 00:53:19 2018-08-04 00:13:20 1.598      1.989
10: test gas     agip F123  dino 2018-08-04 01:09:17 2018-08-05 00:23:20 1.598      1.990
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...