【问题标题】:Extract all BUT the first occurrence of a variable in a data frame提取所有但第一次出现的变量在数据框中
【发布时间】:2015-11-04 14:27:59
【问题描述】:

我有一个像这样的数据框:

ID        DATE  N  Price
 1  2013-02-04  3  29.99
 1  2013-03-18  1   9.99
 1  2013-04-13  2  19.99
 2  2013-02-18  1  18.99
 2  2013-05-11  2  19.99

这个答案Extract rows for the first occurrence of a variable in a data frame 告诉如何提取目标值的第一次出现......但我需要所有但第一次出现,又名:

ID        DATE  N  Price
 1  2013-03-18  1   9.99
 1  2013-04-13  2  19.99
 2  2013-05-11  2  19.99

推荐的方法是什么?

我最初的直觉是使用链接答案中概述的方法,构建“第一个”子集,然后说,“从原始数据框中,给我除了这些值之外的所有内容”......但这似乎更多复杂。

【问题讨论】:

    标签: r


    【解决方案1】:

    您可以使用 data.table 包轻松完成此操作。

    library(data.table)
    setDT(df)[, .SD[-1], by = ID]
    #    ID       DATE N Price
    # 1:  1 2013-03-18 1  9.99
    # 2:  1 2013-04-13 2 19.99
    # 3:  2 2013-05-11 2 19.99
    

    df 是您的原始数据。这将删除按ID 分组的每个组的第一行。

    另一个选项是 dplyr 包。

    library(dplyr)
    slice(group_by(df, ID), -1)
    #      ID       DATE     N Price
    #   (int)     (fctr) (int) (dbl)
    # 1     1 2013-03-18     1  9.99
    # 2     1 2013-04-13     2 19.99
    # 3     2 2013-05-11     2 19.99
    

    这些删除所有组的第一行。如果一个组只有一行,您没有指定应该发生什么。如果您需要保留这些行,则需要考虑这一点。因此,让我们将单行添加为一个组并查看一下。

    dff <- rbind(df, df[4, ])
    dff[6, 1] <- 3
    

    那么 data.table 代码将是

    setDT(dff)[, .SD[if(.N == 1L) 1 else -1], by = ID]
    #    ID       DATE N Price
    # 1:  1 2013-03-18 1  9.99
    # 2:  1 2013-04-13 2 19.99
    # 3:  2 2013-05-11 2 19.99
    # 4:  3 2013-02-18 1 18.99
    

    dplyr 代码是

    slice(group_by(dff, ID), if(n() == 1L) 1 else -1)
    #      ID       DATE     N Price
    #   (dbl)     (fctr) (int) (dbl)
    # 1     1 2013-03-18     1  9.99
    # 2     1 2013-04-13     2 19.99
    # 3     2 2013-05-11     2 19.99
    # 4     3 2013-02-18     1 18.99
    

    针对那些情况。

    数据:

    df <- structure(list(ID = c(1L, 1L, 1L, 2L, 2L), DATE = structure(c(1L, 
    3L, 4L, 2L, 5L), .Label = c("2013-02-04", "2013-02-18", "2013-03-18", 
    "2013-04-13", "2013-05-11"), class = "factor"), N = c(3L, 1L, 
    2L, 1L, 2L), Price = c(29.99, 9.99, 19.99, 18.99, 19.99)), .Names = c("ID", 
    "DATE", "N", "Price"), class = "data.frame", row.names = c(NA, 
    -5L))
    

    【讨论】:

      【解决方案2】:

      如果您不想使用附加包:

      df[duplicated(df$ID),]
      

      【讨论】:

      • 我喜欢它的简单性。我想出的最好的是 df[-match(unique(df$ID), df$ID),] ,但这更好。
      【解决方案3】:

      另一个选项是ave

       df[with(df, ave(ID, ID, FUN= seq_along)!=1),]
       #  ID       DATE N Price
       #2  1 2013-03-18 1  9.99
       #3  1 2013-04-13 2 19.99
       #5  2 2013-05-11 2 19.99
      

      【讨论】:

        猜你喜欢
        • 2013-11-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-08
        • 1970-01-01
        • 1970-01-01
        • 2021-10-16
        • 2018-12-21
        相关资源
        最近更新 更多