【问题标题】:Subset R data frame contingent on the value of duplicate variables子集 R 数据框取决于重复变量的值
【发布时间】:2012-06-28 08:19:32
【问题描述】:

如何子集以下示例数据框以仅返回一个 最早出现的观察[即每个 id 的 min(year)]?

id <- c("A", "A", "C", "D", "E", "F")
year <- c(2000, 2001, 2001, 2002, 2003, 2004)
qty  <- c(100, 300, 100, 200, 100, 500)
df=data.frame(year, qty, id)

在上面的示例中,“A”id 在 2000 年和 2001 年有两个观察结果。在重复 id 的情况下,我希望子集数据框仅包含第一次出现(即 2000 年)重复 id 的观察结果。

df2 = subset(df, ???)

这是我想要返回的:

df2

year qty id
2000 100  A
2001 100  C
2002 200  D
2003 100  E
2004 500  F

任何帮助将不胜感激。

【问题讨论】:

    标签: r dataframe subset plyr data.table


    【解决方案1】:

    你可以聚合最小年份+id,然后与原始数据框合并得到数量:

    df2 <- merge(aggregate(year ~ id, df1, min), df1)
    
    # > df2
    #   id year qty
    # 1  A 2000 100
    # 2  C 2001 100
    # 3  D 2002 200
    # 4  E 2003 100
    # 5  F 2004 500
    

    【讨论】:

      【解决方案2】:

      这就是你要找的吗?您的第二行在我看来是错误的(这是重复的年份,而不是第一行)。

      > duplicated(df$year)
      [1] FALSE FALSE  TRUE FALSE FALSE FALSE
      > df[!duplicated(df$year), ]
        year qty id
      1 2000 100  A
      2 2001 300  A
      4 2002 200  D
      5 2003 100  E
      6 2004 500  F
      

      编辑1:呃,我完全误解了你的要求。不过,为了完整起见,我会将其保留在这里。

      编辑 2:

      好的,这是一个解决方案:按年份排序(因此每个 ID 的第一个条目具有最早的年份),然后使用 duplicated。我认为这是最简单的解决方案:

      > df.sort.year <- df[order(df$year), ]
      > df.sort.year[!duplicated(df$id),  ]
        year qty id
      1 2000 100  A
      3 2001 100  C
      4 2002 200  D
      5 2003 100  E
      6 2004 500  F
      

      【讨论】:

        【解决方案3】:

        使用 plyr

        library(plyr)
        ## make sure first row will be min (year)
        df <- arrange(df, id, year)
        df2 <- ddply(df, .(id), head, n = 1)
        
        
        df2
        ##   year qty id
        ## 1 2000 100  A
        ## 2 2001 100  C
        ## 3 2002 200  D
        ## 4 2003 100  E
        ## 5 2004 500  F
        

        或使用 data.table。将键设置为 id,year 将确保第一行是年份的最小值。

        library(data.table)
        DF <- data.table(df, key = c('id','year'))
        DF[,.SD[1], by = 'id']
        
        ##      id year qty
        ## [1,]  A 2000 100
        ## [2,]  C 2001 100
        ## [3,]  D 2002 200
        ## [4,]  E 2003 100
        ## [5,]  F 2004 500
        

        【讨论】:

        • 另外,对于大型 data.tables,这可能会更快:DF[J(unique(DF[,id])), mult="first"]
        【解决方案4】:

        可能有一种更漂亮的方法,但这就是我想到的

        # use which() to get index for each id, saving only first
        first_occurance <- with(df, sapply(unique(id), function(x) which(id %in% x)[1]))
        df[first_occurance,]
        #  year qty id
        #1 2000 100  A
        #3 2001 100  C
        #4 2002 200  D
        #5 2003 100  E
        #6 2004 500  F
        

        【讨论】:

          猜你喜欢
          • 2016-03-29
          • 2012-05-26
          • 2017-04-06
          • 2023-03-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-11
          • 1970-01-01
          相关资源
          最近更新 更多