【问题标题】:R remove all but the first occurenceR 删除除第一次出现外的所有内容
【发布时间】:2017-12-14 23:42:22
【问题描述】:

我有一个如下所示的数据框:

  id     date  time
1  1 15-12-15 10:30
2  2 15-12-15 08:30
3  3 16-12-15 10:30
4  1 16-12-15 08:30

可以这样创建:

df <- data.frame(id=c(1,2,3,1),
                 date=c("15-12-15", "15-12-15", "16-12-15", "16-12-15"),
                 time=c("10:30", "08:30", "10:30", "08:30"))

我想删除所有具有重复 id 的行。如果发现重复项,那么我想保留最先出现的id(按日期和时间),并删除所有其他人

我目前的做法是按date排序,然后:

df <- subset(df, duplicated(df$id) == FALSE)

因此,这将保留 id 不重复但保留标准不明确的所有行。它似乎只保留按日期排序时遇到的第一次出现?

有没有一种方法可以做到这一点而不必先进行日期排序?

【问题讨论】:

    标签: r sorting dataframe subset


    【解决方案1】:

    你可能需要这样的东西:

    library(dplyr)
    df %>%
       group_by(id) %>%
       mutate(datetime = as.POSIXct(paste(date, time), format = "%d-%m-%y %H:%M")) %>%
       arrange(datetime) %>%
       slice(1) %>%
       select(-datetime)
    
    
    #     id     date   time           
    #  <dbl>   <fctr> <fctr>           
    #1     1 15-12-15  10:30 
    #2     2 15-12-15  08:30 
    #3     3 16-12-15  10:30 
    

    我们创建一个POSIXct 对象,将datetime 列粘贴在一起,arrange 相应地从每个组中选择第一个观察值(最早出现的观察值)。

    【讨论】:

      【解决方案2】:

      我们需要fromLast = TRUE

      df[!duplicated(df$id, fromLast = TRUE),]
      #    id     date  time
      #2  2 15-12-15 08:30
      #3  3 16-12-15 10:30
      #4  1 16-12-15 08:30
      

      如果我们需要考虑“日期”和“时间”(在示例中已经排序)

      library(lubridate)
      df[!duplicated(df$id[with(df, order(id, ymd_hm(paste(date, time))))], fromLast = TRUE),]
      #    id     date  time
      #2  2 15-12-15 08:30
      #3  3 16-12-15 10:30
      #4  1 16-12-15 08:30
      

      【讨论】:

        【解决方案3】:

        data.table 包含一个增强的unique() 函数,它接受by 参数来指定用于唯一性检查的列:

        library(data.table)
        unique(setDT(df, key = c("date", "time")), by = "id")
        
           id     date  time
        1:  2 15-12-15 08:30
        2:  1 15-12-15 10:30
        3:  3 16-12-15 10:30
        

        setDT()df 强制转换为 data.table 类。 key 参数对df 进行排序并将其标记为已排序。

        【讨论】:

          【解决方案4】:

          使用dplyr 的另一种方法是:

          df %>% 
            group_by(id) %>%
            arrange(date, time) %>%
            top_n(1)
          

          给出:

               id     date   time
            <dbl>   <fctr> <fctr>
          1     2 15-12-15  08:30
          2     1 15-12-15  10:30
          3     3 16-12-15  10:30
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-12-03
            • 2012-02-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多