【问题标题】:selecting data from a R data table from a set of variables occurring at same timestamp从同一时间戳发生的一组变量中从 R 数据表中选择数据
【发布时间】:2019-11-19 11:25:24
【问题描述】:

我有一个像这样的 R 数据表:

time                var val
01-07-2019 13:27:31 X   5
01-07-2019 13:27:31 Y   10
01-07-2019 13:27:31 Z   12
01-07-2019 13:28:20 X   13
01-07-2019 13:28:20 Y   12
01-07-2019 13:28:20 Z   15
01-07-2019 13:49:54 X   3
01-07-2019 13:49:54 Y   3
01-07-2019 13:49:54 Z   4
01-07-2019 13:50:25 X   13
01-07-2019 13:50:25 Y   11
01-07-2019 13:50:25 Z   10

一组变量在同一时间重复。所以在每个时间戳都有一组。 如何在同一timestamp中提取匹配条件的行,如X>10 & Y<15

预期输出:

time                var val
01-07-2019 13:28:20 X   13
01-07-2019 13:28:20 Y   12
01-07-2019 13:28:20 Z   15
01-07-2019 13:50:25 X   13
01-07-2019 13:50:25 Y   11
01-07-2019 13:50:25 Z   10

【问题讨论】:

    标签: r datatable


    【解决方案1】:

    使用base R时有两种方法:

    解决方案 1:您可以先重塑您的 df,然后使用 subset 来满足条件

    u <- subset(reshape(df,idvar = "time",timevar = "var", direction = "wide"),val.X>10, val.Y < 15)
    > u
                      time val.X val.Y val.Z
    4  01-07-2019 13:28:20    13    12    15
    10 01-07-2019 13:50:25    13    11    10
    

    然后

    > df[!is.na(match(df$time,u$time)),]
                      time var val
    4  01-07-2019 13:28:20   X  13
    5  01-07-2019 13:28:20   Y  12
    6  01-07-2019 13:28:20   Z  15
    10 01-07-2019 13:50:25   X  13
    11 01-07-2019 13:50:25   Y  11
    12 01-07-2019 13:50:25   Z  10
    

    解决方案2:也可以使用split将数据框分割成time

    z <- split(df,df$time)
    Reduce(rbind,z[sapply(z,function(v) with(v,ifelse(val[var=="X"]>10 & val[var=="Y"]<15,T,F)))])
    

    然后

    > Reduce(rbind,z[sapply(z,function(v) with(v,ifelse(val[var=="X"]>10 & val[var=="Y"]<15,T,F)))])
                      time var val
    4  01-07-2019 13:28:20   X  13
    5  01-07-2019 13:28:20   Y  12
    6  01-07-2019 13:28:20   Z  15
    10 01-07-2019 13:50:25   X  13
    11 01-07-2019 13:50:25   Y  11
    12 01-07-2019 13:50:25   Z  10
    

    数据

    df <- structure(list(time = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 
    3L, 3L, 4L, 4L, 4L), .Label = c("01-07-2019 13:27:31", "01-07-2019 13:28:20", 
    "01-07-2019 13:49:54", "01-07-2019 13:50:25"), class = "factor"), 
        var = structure(c(1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 
        2L, 3L), .Label = c("X", "Y", "Z"), class = "factor"), val = c(5L, 
        10L, 12L, 13L, 12L, 15L, 3L, 3L, 4L, 13L, 11L, 10L)), class = "data.frame", row.names = c(NA, 
    -12L))
    

    【讨论】:

      【解决方案2】:

      这是一个选项:

      # Define helper function foo:
      foo <- function(x, y) any(x == "X" & y > 10) & any(x == "Y" & y < 15)
      
      DT[, .SD[foo(var, val)], by = time]
      

      【讨论】:

        【解决方案3】:

        整洁的答案

        library(dplyr)
        library(lubridate)
        
        dataExample <- data.frame(
        time = c(
        '01-07-2019 13:27:31',
        '01-07-2019 13:27:31',
        '01-07-2019 13:27:32',
        '01-07-2019 13:27:32',
        '01-07-2019 13:27:30'),
        var = c("X","Y","X","Y","X"),
        val = c(4,5,3,5,9))
        
        #Convert from character to date-time
        dataExample$time <- dmy_hms(dataExample$time) 
        
        dataExample %>% group_by(time) %>% 
        filter((var == "X" & val > 4) | (var == "Y" & val < 8))
        

        返回

        # A tibble: 3 x 3
        # Groups:   time [3]
          time                var     val
          <dttm>              <fct> <dbl>
        1 2019-07-01 13:27:31 Y         5
        2 2019-07-01 13:27:32 Y         5
        3 2019-07-01 13:27:30 X         9
        

        【讨论】:

          【解决方案4】:

          有几种方法可以做到这一点:

          1. 创建过滤掉 X=15 值的数据集。然后,您只需要检查每个时间戳的数据集中是否存在 X 和 Y 的值。 您可以使用 dataset[, anyX := any(var=="X"), by = time]
          2. 检查每次在数据集中保留哪些 var 值
          3. 将数据集重塑为宽格式,然后一次检查这两个条件很简单。您还需要检查 NA。此方法假定您不能在时间戳上为 var 的每个值设置多个值。
          4. 过滤数据集以选择 X 和 Y 符合您的条件的时间戳。然后删除不符合条件的 X 和 Y 值(如果您不能在一个时间戳中拥有多个 X 和 Y,则可能不需要这样做。
          dt[,outputTime:=any(var=="X"&val>10) | any(var=="Y"&val<15),by=time][outputTime==TRUE][,outputTime:=NULL][var=="X"&val>10|var=="Y"&val<10|var=="Z"]
          

          【讨论】:

            猜你喜欢
            • 2013-05-04
            • 2021-08-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-12-14
            • 2017-06-15
            相关资源
            最近更新 更多