#r #dplyr #data.table #zoo
#r #dplyr #данные.таблица #зоопарк
Вопрос:
У меня есть фрейм данных test
> test
foo bar baz timestamp
1 1 <NA> a 1552157998
2 1 <NA> <NA> 1552161596
3 1 stop <NA> 1552165194
4 1 <NA> b 1552168795
5 1 <NA> a 1552170839
6 1 <NA> <NA> 1552157998
7 1 stop <NA> 1552161596
8 1 <NA> a 1552165194
9 1 <NA> b 1552168795
10 1 <NA> <NA> 1552170839
Моя цель — найти для каждого экземпляра stop
ближайшее значение, отличное от NA, в каждом направлении (на основе timestamp
), которое создало бы таблицу, подобную этой:
> output
rownum pre post
1 3 a b
2 7 a a
Есть ли известный способ сделать это с zoo
помощью and na.locf()
?
Любые предложения будут оценены
dput(test)
structure(list(foo = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1), bar = c(NA,
NA, "stop", NA, NA, NA, "stop", NA, NA, NA), baz = c("a", NA,
NA, "b", "a", NA, NA, "a", "b", NA), timestamp = c(1552157998.427,
1552161596.004, 1552165194.255, 1552168794.918, 1552170839.363,
1552157998.427, 1552161596.004, 1552165194.255, 1552168794.918,
1552170839.363)), row.names = c(NA, -10L), class = "data.frame")
Комментарии:
1. Не могли бы вы включить
timestamp
столбец в свойdput
?2. да, я это сделал — отредактировано
3. Использует ли последующие элементы один и тот же pre / post?
4. @akrun да, то же самое
5. Поскольку вы упомянули «на основе метки времени»: предполагается ли упорядочивать набор данных перед определением следующего / предыдущего элемента. Потому что я получаю другой результат, если это так
Ответ №1:
Я буду использовать magrittr
исключительно для организации кода. Это можно так же легко перевести в не- magrittr
, dplyr
, или data.table
с минимальными усилиями.
library(magrittr)
test %>%
.[ order(.$timestamp), ] %>%
transform(.,
rownum = seq_len(nrow(.)),
pre = zoo::na.locf0(baz),
post = zoo::na.locf0(baz, fromLast = TRUE)) %>%
subset(., bar == "stop") %>%
.[, c("rownum", "pre", "post")]
# rownum pre post
# 7 4 a a
# 3 5 a a
(Это отличается от ожидаемого результата, возможно, потому, что это ошибка?)
Вы можете немного лучше понять, что это делает, посмотрев на него раньше subset
:
test %>%
.[ order(.$timestamp), ] %>%
transform(.,
rownum = seq_len(nrow(.)),
pre = zoo::na.locf0(baz),
post = zoo::na.locf0(baz, fromLast = TRUE))
# foo bar baz timestamp rownum pre post
# 1 1 <NA> a 1552157998 1 a a
# 6 1 <NA> <NA> 1552157998 2 a a
# 2 1 <NA> <NA> 1552161596 3 a a
# 7 1 stop <NA> 1552161596 4 a a
# 3 1 stop <NA> 1552165194 5 a a
# 8 1 <NA> a 1552165194 6 a a
# 4 1 <NA> b 1552168795 7 b b
# 9 1 <NA> b 1552168795 8 b b
# 5 1 <NA> a 1552170839 9 a a
# 10 1 <NA> <NA> 1552170839 10 a <NA>
Комментарии:
1. Если я закажу
data.frame
здесь, я получу другой результат: post равно «a» для обоих индексов.2. Нет в предоставленном вами примере. Возможно, вы можете обновить его и / или использовать любой имеющийся у вас код, который дает результаты, отличные от этих?
3. Я не предоставил никакого образца. Ваш код здесь не работает, потому что он не будет упорядочен по временной метке
test[order(timestamp),]
test[order(test$timestamp),]
, иначе он выдаст ошибку и не отсортирует df перед выполнением rest // PS: на самом деле это не проблема с вашим кодом (помимо проблемы с упорядочением), я думаю, что желаемый результат ОПЕРАЦИИ просто неправильно для упорядоченного df.