繁体   English   中英

将dplyr的超前或滞后与其他变量结合使用

[英]using lead or lag from dplyr in combination with other variables

我有一个数据框:

                 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行,其中Type等于“ 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")

1)如果目标是找到比第一个1415行超出的第一个LiveWire行的行号,则使用所示的结合LiveWire然后使用whichfirst获取行号和那些行号中的第一个。 请注意,对于1415年以后的第一个Data组件, cummany是正确的,并且通过将其滞后,我们只对它之后的那些正确。 如果我们知道只有这样一行,那么我们可以省略first 由于与dplyr的滞后冲突lag的基础,我们使用dplyr::lag ,以确保我们使用所需的一个。

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

2)如果我们想要行本身,则使用filterslice 如果我们知道只有这样的一行,我们可以省略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

更新

修订。

我正在使用dplyr的超前和滞后函数来获取特定行之前和之后的数据点。 我可以使用相同/相似的功能来在下一个“ LiveView”中获取数据吗?

如果对于Data == 1415的每个实例,您要查找CardID匹配,Type匹配且Time较大的下一行,则...

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。

一种方法是基于Type的数据dplyr::group_bydplyr::filter感兴趣的Type ,然后dplyr::slice到您想要的位置,在这种情况下为position 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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM