подмножество data.frame: очень странное поведение при использовании цифры c разница в дате - PullRequest
0 голосов
/ 03 мая 2020

Существует поведение, которое я не понимаю при подстановке кадра данных с датами. Вот пример (данные в конце):

> df
   positif1 positif2      date1      date2
1         0        0 2020-05-02 2020-04-30
2         0        0 2020-05-02 2020-04-21
3         0        0 2020-05-02 2020-04-30
.
.

Я наивно хотел поднастроить это:

df[df$positif2 == 0 & df$positif1 == 0 & as.numeric(df$date1 - df$date2) <=2,]

, и он ничего не возвращает, хотя есть явно значения, соответствующие условие:

as.numeric(df[df$positif2 == 0 & df$positif1 == 0,"date1"]-df[df$positif2 == 0 & df$positif1 == 0,"date2"])
 [1]  2 11  2 29 12 18  1 22  5 24  5  6  4 25  9  9 13 16 17 35  5 35 22 51  3 17  8 16 12 15 14 21 14
[34]  4

Я понял, что правильно сделать:

df[df$positif2 == 0 & df$positif1 == 0 & difftime(df$date1, df$date2,units = "day") <=2,]

и что моя проблема заключалась в том, что единица изменяется при поднаборе фрейма данных или нет:

> df$date1 - df$date2
Time differences in secs
 [1]  172800  950400  172800 2505600 1036800 1555200 2073600   86400 1900800  432000 2073600  432000
[13]  518400  345600 2160000  777600  777600       0 1123200 1382400 1468800 3024000       0  432000
[25] 3024000 1900800 4406400       0  259200 1468800  691200 1382400 1036800 1296000 1209600 1814400
[37] 1209600  345600


> df[df$positif2 == 0,"date1"] - df[df$positif2 == 0,"date2"]
Time differences in days
 [1]  2 11  2 29 12 18 24  1 22  5 24  5  6  4 25  9  9 13 16 17 35  5 35 22 51  3 17  8 16 12 15 14 21
[34] 14  4

Это не имеет смысла для меня. Я что-то не так делаю? Есть ли причина для такого поведения?


data:

df <- structure(list(positif1 = c(0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0), positif2 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 1L, 0L, 
0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), date1 = structure(c(1588377600, 
1588377600, 1588377600, 1588377600, 1588377600, 1588377600, 1588377600, 
1588377600, 1588377600, 1588377600, 1588377600, 1588377600, 1588377600, 
1588377600, 1588377600, 1588377600, 1588377600, 1584057600, 1588377600, 
1588377600, 1588377600, 1588377600, 1586563200, 1588377600, 1588377600, 
1588377600, 1588377600, 1586908800, 1588377600, 1588377600, 1588377600, 
1588377600, 1588377600, 1588377600, 1588377600, 1588377600, 1588377600, 
1588377600), class = c("POSIXct", "POSIXt"), tzone = "UTC"), 
    date2 = structure(c(1588204800, 1587427200, 1588204800, 1585872000, 
    1587340800, 1586822400, 1586304000, 1588291200, 1586476800, 
    1587945600, 1586304000, 1587945600, 1587859200, 1588032000, 
    1586217600, 1587600000, 1587600000, 1584057600, 1587254400, 
    1586995200, 1586908800, 1585353600, 1586563200, 1587945600, 
    1585353600, 1586476800, 1583971200, 1586908800, 1588118400, 
    1586908800, 1587686400, 1586995200, 1587340800, 1587081600, 
    1587168000, 1586563200, 1587168000, 1588032000), class = c("POSIXct", 
    "POSIXt"), tzone = "UTC")), row.names = c(NA, -38L), class = "data.frame", index = structure(integer(0), "`__positif1__positif2`" = c(1L, 
2L, 3L, 4L, 5L, 6L, 8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 16L, 
17L, 19L, 20L, 21L, 22L, 24L, 25L, 26L, 27L, 29L, 30L, 31L, 32L, 
33L, 34L, 35L, 36L, 37L, 38L, 7L, 18L, 23L, 28L)))

1 Ответ

1 голос
/ 03 мая 2020

С ?difftime

Вычитание объектов даты и времени дает объект этого класса, вызывая difftime с units = "auto".

Итак, по умолчанию мы знаем units = "auto" при вычитании дат.

Во-вторых,

Если unit = "auto", выбирается подходящий набор единиц, максимально возможный (исключая "недели"), в котором все абсолютные различия больше, чем один.

Поэтому, когда units = "auto", он пытается выбрать единицу, которая является самой большой. Поэтому, когда мы делаем

df$date1 - df$date2

Есть определенные записи, которые одинаковы в date1 и date2, с разницей в 0, поэтому здесь в качестве единицы выбраны «секунды».

Но если вы установите в 0 positif2 (positif2 == 0) даты только для 0 записей, минимальная разница будет в датах, поэтому выбранная единица измерения - "дни".

df$date1[df$positif2 == 0] - df$date2[df$positif2 == 0]

Как вы уже определили, правильный путь - использовать difftime и явно указать в нем аргумент units.

...