按基本 R 中的重复行对数据框进行排序?

Posted

技术标签:

【中文标题】按基本 R 中的重复行对数据框进行排序?【英文标题】:Sort a data frame by its duplicated rows in base R? 【发布时间】:2021-08-03 04:51:56 【问题描述】:

考虑flights 数据:

library(nycflights13)
flights
# A tibble: 336,776 x 19
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time arr_delay carrier flight tailnum
   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>     <dbl> <chr>    <int> <chr>  
 1  2013     1     1      517            515         2      830            819        11 UA        1545 N14228 
 2  2013     1     1      533            529         4      850            830        20 UA        1714 N24211 
 3  2013     1     1      542            540         2      923            850        33 AA        1141 N619AA 
 4  2013     1     1      544            545        -1     1004           1022       -18 B6         725 N804JB 
 5  2013     1     1      554            600        -6      812            837       -25 DL         461 N668DN 
 6  2013     1     1      554            558        -4      740            728        12 UA        1696 N39463 
 7  2013     1     1      555            600        -5      913            854        19 B6         507 N516JB 
 8  2013     1     1      557            600        -3      709            723       -14 EV        5708 N829AS 
 9  2013     1     1      557            600        -3      838            846        -8 B6          79 N593JB 
10  2013     1     1      558            600        -2      753            745         8 AA         301 N3ALAA 
# … with 336,766 more rows, and 7 more variables: origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
#   hour <dbl>, minute <dbl>, time_hour <dttm>

我确信许多tailnum 条目是重复的。 anyDuplicated 会确认这一点,但我想并排查看重复项。我能想到的最好的方法是:

flights[duplicated(flights$tailnum),]->dups
dups[order(dups$tailnum),]
# A tibble: 332,732 x 19
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time arr_delay carrier flight tailnum
   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>     <dbl> <chr>    <int> <chr>  
 1  2013     3    23     1340           1300        40     1638           1554        44 DL        1685 D942DN 
 2  2013     3    24      859            835        24     1142           1140         2 DL        1959 D942DN 
 3  2013     7     5     1253           1259        -6     1518           1529       -11 DL         781 D942DN 
 4  2013     1     1     2100           2100         0     2307           2250        17 MQ        4584 N0EGMQ 
 5  2013     1     2      827            835        -8     1059           1105        -6 MQ        4610 N0EGMQ 
 6  2013     1     2     2014           2020        -6     2256           2245        11 MQ        4662 N0EGMQ 
 7  2013     1     4     1621           1625        -4     1853           1855        -2 MQ        4661 N0EGMQ 
 8  2013     1     5      834            835        -1     1050           1105       -15 MQ        4610 N0EGMQ 
 9  2013     1     6      832            835        -3     1101           1105        -4 MQ        4610 N0EGMQ 
10  2013     1     6     2051           2100        -9     2241           2250        -9 MQ        4584 N0EGMQ 
# … with 332,722 more rows, and 7 more variables: origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
#   hour <dbl>, minute <dbl>, time_hour <dttm>

这给出了所需的输出,但我发现输入非常难看。有没有更好的方法?这似乎是管道的自然用例,但考虑到基本 R 没有该功能已有多长时间,我希望能找到一个很好的替代方案。我希望能够以某种方式编写orderduplicated,但我没有想到任何方法。

【问题讨论】:

R 的当前开发版本允许使用|&gt; 进行管道传输,例如:flights[duplicated(flights$tailnum),] |&gt; (function(.) .[order(.$tailnum),])() 【参考方案1】:

tidyverse,这可以通过管道传输

library(dplyr)
flights %>%
    filter(duplicated(tailnum)) %>% 
    arrange(tailnum)

但在base R 中,问题在于如果不使用管道,即外部包或分配给不同的对象,可能不得不通过调用duplicated 两次来降低效率

subset(flights, duplicated(tailnum))[
     with(flights, order(tailnum[duplicated(tailnum)])),]

或与magrittr结合使用

subset(flights, duplicated(tailnum)) %>%
       .[order(.$tailnum), ] 

【讨论】:

我会接受基本 R 中的任何内容,只要它以一种看起来比我使用的工作更少的方式提供相同的输出。特别是,我更喜欢一条线而不是两条线。 @J.Mini 你是在寻找效率还是代码打高尔夫球 我倾向于打高尔夫球。无需走极端。 @J.Mini 我认为base R 正在建设一条管道,这将使管道更清洁。 有。我记得,这是下一个版本。【参考方案2】:

你可以试试这个。

r2 <- with(flights, flights[o <- order(r <- rank(tailnum, na.last='keep')), ][duplicated(r[o]), ])

在哪里

flights[duplicated(flights$tailnum),]->dups
r1 <- dups[order(dups$tailnum),]
stopifnot(all.equal(r1, r2))

【讨论】:

以上是关于按基本 R 中的重复行对数据框进行排序?的主要内容,如果未能解决你的问题,请参考以下文章

从数据框中删除行的命令[重复]

按r中的列对数据帧进行排序[重复]

重新排序数据框中的因子水平[重复]

仅按第二行对 np 二维数组进行排序[重复]

如何按 R 中的第二列排序数据框? [复制]

如何按行对数据进行排序? [MYSQL]