использование опережения или отставания от dplyr в сочетании с другими переменными - PullRequest
0 голосов
/ 12 сентября 2018

У меня есть фрейм данных:

                 Time   CardID    Data      Type
1  2018-01-01 10:44:35 10037479 PowerOn  STBEvent
2  2018-01-01 10:44:48 10037479    0401 UseRemote
3  2018-01-01 10:44:53 10037479    0301 UseRemote
4  2018-01-01 10:45:13 10037479    0401 UseRemote
5  2018-01-01 10:45:24 10037479    0301 UseRemote
6  2018-01-01 10:45:30 10037479    1415  LiveView
7  2018-01-01 10:45:37 10037479    0401 UseRemote
8  2018-01-01 11:08:01 10037479    1412  LiveView
9  2018-01-01 11:08:13 10037479    0401 UseRemote
10 2018-01-01 11:14:31 10037479    0301 UseRemote

structure(list(Time = structure(c(1514783675, 1514783688, 1514783693, 
1514783713, 1514783724, 1514783730, 1514783737, 1514785081, 1514785093, 
1514785471), class = c("POSIXct", "POSIXt")), CardID = c("10037479", 
"10037479", "10037479", "10037479", "10037479", "10037479", "10037479", 
"10037479", "10037479", "10037479"), Data = c("PowerOn", "0401", 
"0301", "0401", "0301", "1415", "0401", "1412", "0401", "0301"
), Type = c("STBEvent", "UseRemote", "UseRemote", "UseRemote", 
"UseRemote", "LiveView", "UseRemote", "LiveView", "UseRemote", 
"UseRemote")), .Names = c("Time", "CardID", "Data", "Type"), row.names = c(NA, 
10L), class = "data.frame")

Я использую функции опережения и запаздывания из dplyr для выборки точек данных до и после определенной строки.Например, я использую это:

ae1 <- which(dplyr::lag(df$Data)=="1415")+1

Это дает мне номер строки 6 из вышеупомянутого фрейма данных, где тип равен "LiveView".Я понимаю, что, изменив целое число в конце кода, я мог бы получить соответствующую строку из фрейма данных.У меня вопрос: могу ли я использовать ту же / аналогичную функцию, в которой я могу получать данные для следующего «LiveView» - строки № 8. Я вполне могу сделать

ae1 <- which(dplyr::lag(df$Data)=="1415")+3

, чтобы получить строку № 8. Носледующий тип LiveView может появляться в любой строке, кроме 8. Я думаю, что-то похожее на

ae1 <- which(dplyr::lag(df$Data)=="1415")+nrow(where Type == next "LiveView")

Ответы [ 3 ]

0 голосов
/ 12 сентября 2018

1) Если цель состоит в том, чтобы найти номер строки первой LiveWire строки после первой строки 1415, то используйте показанное соединение, а затем which и first, чтобы получить строкуномера и первый из этих номеров строк.Обратите внимание, что cummany верно для первого Data компонента 1415 года и, отставая от него, мы получаем истину только для тех, кто после него до конца.Если бы мы знали, что существует только одна такая строка, мы могли бы опустить first.Поскольку лаг в dplyr конфликтует с lag в базе, мы используем dplyr::lag, чтобы убедиться, что мы используем нужный.

df %>% 
  { dplyr::lag(cumany(.$Data == 1415)) & .$Type == "LiveView" } %>%
  which %>%
  first
  ## [1] 8

2) Если вместо этого нам нужна сама строказатем используйте filter и slice.Если бы мы знали, что есть только одна такая строка, мы могли бы опустить slice:

df %>% 
  filter(dplyr::lag(cumany(Data == 1415)) & Type == "LiveView") %>%
  slice(1)
##                  Time   CardID Data     Type
## 1 2018-01-01 00:38:01 10037479 1412 LiveView

Обратите внимание, что если мы добавим номер строки к df, заменив первую строку кода на:

df %>% mutate(n = 1:n()) %>%

, тогда приведенный выше код также даст номер строки в столбце n в дополнение к самой строке в других столбцах.

2a) Альтернатива(2) мы можем сначала отфильтровать по cumany(Data == 1415), чтобы получить все строки от первой строки 1415 и далее, а затем удалить первую строку, поскольку нам нужны только строки после , а затем найти строки LiveViewвнутри этого и возьмите первое.

df %>% 
  filter(cumany(Data == 1415)) %>%
  slice(-1) %>%
  filter(Type == "LiveView") %>%
  slice(1)
##                  Time   CardID Data     Type
## 1 2018-01-01 00:38:01 10037479 1412 LiveView

Обновление

Пересмотрено.

0 голосов
/ 12 сентября 2018

Я использую функции опережения и отставания от dplyr для выборки точек данных до и после определенной строки.[...] могу ли я использовать ту же / аналогичную функцию, в которой я могу получать данные в следующем "LiveView" [?]

Если для каждого экземпляра данных == 1415, вы хотите найтиследующая строка, в которой CardID совпадает, тип совпадает, а время больше, тогда есть ...

library(data.table)
setDT(df)

mdf = df[Data == "1415", .(CardID, Type, Time)]
w   = df[mdf, on=.(CardID, Type, Time > Time), mult="first", which=TRUE]
df[w]

#                   Time   CardID Data     Type
# 1: 2018-01-01 00:38:01 10037479 1412 LiveView

Если у вас есть повторяющиеся времена, то Time не будет работать как номер строки.Вы можете добавить номер строки, например df[, rn := .I] или df[, rn := rowid(CardID)], и использовать его вместо этого.

Строка с on= является неэквивалентным соединением, в настоящее время недоступным в dplyr, поэтому япроводка с другим пакетом здесь.


Если вы хотите вернуть обе строки ....

w0 = df[Data == "1415", which=TRUE]
w  = df[df[w0], on=.(CardID, Type, Time > Time), mult="first", which=TRUE]
df[matrix(c(w0, w), 2, byrow=TRUE)]

#                   Time   CardID Data     Type
# 1: 2018-01-01 00:15:30 10037479 1415 LiveView
# 2: 2018-01-01 00:38:01 10037479 1412 LiveView

Или если вам также нужны точки данных перед строкой:

wb = df[df[w0], on=.(CardID, Type, Time < Time), mult="first", which=TRUE]
df[matrix(c(wb, w0, w), 3, byrow=TRUE)]

#                   Time   CardID Data     Type
# 1:                <NA>     <NA> <NA>     <NA>
# 2: 2018-01-01 00:15:30 10037479 1415 LiveView
# 3: 2018-01-01 00:38:01 10037479 1412 LiveView

NA показаны, поскольку ни одна строка не соответствует этим критериям.

0 голосов
/ 12 сентября 2018

Один из способов сделать это - dplyr::group_by данные, основанные на Type, dplyr::filter Type интереса, а затем dplyr::slice до требуемой позиции, в данном случае, позиции 2:

library(dplyr)

df <- 
  structure(
    list(
      Time = 
        structure(c(1514783675, 1514783688, 1514783693, 
                    1514783713, 1514783724, 1514783730, 1514783737, 1514785081, 1514785093, 
                    1514785471), class = c("POSIXct", "POSIXt")), 
      CardID = c("10037479", "10037479", "10037479", "10037479", "10037479", "10037479", "10037479", 
                 "10037479", "10037479", "10037479"), 
      Data = c("PowerOn", "0401", "0301", "0401", "0301", "1415", "0401", "1412", "0401", "0301"), 
      Type = c("STBEvent", "UseRemote", "UseRemote", "UseRemote", 
               "UseRemote", "LiveView", "UseRemote", "LiveView", "UseRemote", 
               "UseRemote")), 
    .Names = c("Time", "CardID", "Data", "Type"), 
    row.names = c(NA, 10L), 
    class = "data.frame")


df %>% 
group_by(Type) %>% 
filter(Type %in% 'LiveView') %>% 
slice(2)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...