首页 > 解决方案 > 从 data.table 或 head() 中选择“前 n”列时,R 从底层向量返回级别

问题描述

我有一个钓鱼数据的df:

| year | taxon_name    | amount (tonnes) |
 1950    Gadus morhua    100
 1951    Gadus morhua    120
 1952    Gadus morhua    140
 1953    Gadus morhua    130
 1954    Gadus morhua    210
 1950    Sebastes        234
 1951    Sebastes        123
 1952    Sebastes        627
 1953    Sebastes        542
 1954    Sebastes        303

... ETC。

我知道如何使用几种方法选择前 4 种捕捞物种,例如使用data.table

top4 <- setDT(discards_tax)[, .(amount = sum(amount)), by = taxon_name][order(-amount)][1:4, , ] # aggregate catch by taxon, order from highest to lowest catch & grab the top 4

aggregateorderand一起使用head()

top4d <- aggregate(amount ~ taxon_name, discards_tax, sum) # aggregate catch by taxon
top4d <- top4d[order(-top4d$amount),] %>% head(4) # order df from highest to lowest catch & grab the top 4

这两种情况都产生了这个成功的结果,旧的行号:

rowid | taxon_name                   | amount
   33   Melanogrammus aeglefinus       14922534
   60   Sebastes                       14274663
   25   Gadus morhua                   6237214
   53   Reinhardtius hippoglossoides   2466558

我的问题是,在此之后,我一直在尝试制作taxon_name前 4 个 s 的向量列表 - 但每次我尝试这样做(即toptaxa <- top4d$taxon_name)它都会从我的钓鱼数据集中吐出所有 67 个原始分类群!最初我认为这是一个设计特征,data.table但无论我使用什么方法,都会发生这种情况,很明显我没有正确理解它。

之前也有人问过类似的问题(例如,为什么从 data.table 中选择列会产生副本?)但我不确定我是否看到了一个答案,可以让我只从我的结果中进行选择。如何仅操纵前 4 名排序的结果?

编辑这里是我的数据集:https ://www.dropbox.com/s/izn7sdpeosvg1nj/discards_for_stack.csv?dl=0

标签: rdata.tablehead

解决方案


使用data.table方法。

library(data.table)
top4 <- setDT(df)[, .(amount = sum(amount)), by = taxon_name][order(-amount)][1:4, ]

toptaxa <- top4$taxon_name
#[1] "Sebastes"     "dummy2"       "dummy1"       "Gadus morhua"

Base-R聚合方法:

top4d <- aggregate(amount ~ taxon_name, df, sum)
top4d <- top4d[order(-top4d$amount),] %>% head(4)

toptaxa <- top4d$taxon_name

toptaxa
#[1] "Sebastes"     "dummy2"       "dummy1"       "Gadus morhua"

让我们检查另一个选项,使用dplyr包来汇总数据,最后用于slice获取前 4 个物种。

library(dplyr)

df %>% group_by(taxon_name) %>%
  summarise(amount = sum(amount.tonnes.)) %>%
  arrange(desc(amount)) %>%
  slice(1:4) %>%
  select(taxon_name) -> TopNames

#Check the result
TopNames

# # A tibble: 4 x 1
# taxon_name  
# <chr>       
# 1 Sebastes    
# 2 dummy2      
# 3 dummy1      
# 4 Gadus morhua

编辑:使用共享的数据OP

df <- read.csv("D:\\Learning\\R\\discards_for_stack.csv", header = TRUE, stringsAsFactors = FALSE)
top4d <- aggregate(amount ~ taxon_name, df, sum)
top4d <- top4d[order(-top4d$amount),] %>% head(4)

top4d
#                      taxon_name   amount
# 33     Melanogrammus aeglefinus 14922534
# 60                     Sebastes 14274663
# 25                 Gadus morhua  6237214
# 53 Reinhardtius hippoglossoides  2466558

toptaxa <- top4d$taxon_name
toptaxa
# [1] "Melanogrammus aeglefinus"     "Sebastes"                     "Gadus morhua"                
# [4] "Reinhardtius hippoglossoides"

数据: 在 OP 玩具数据集中添加了一些额外的行以作为一个合理的示例。

df <- read.table(text = 
"year  taxon_name     amount(tonnes)
1950    'Gadus morhua'    100
1951    'Gadus morhua'    120
1952    'Gadus morhua'    140
1953    'Gadus morhua'    130
1954    'Gadus morhua'    210
1950    Sebastes        234
1951    Sebastes        123
1952    Sebastes        627
1951    dummy1        123
1952    dummy1        627
1951    dummy2        567
1952    dummy2        627
1951    dummy3        567
1952    dummy4        627
1953    Sebastes        542
1954    Sebastes        303",
header = TRUE, stringsAsFactors = FALSE)

推荐阅读