当从 data.table 或 head() 中选择 "top n" 列时,来自基础向量的 R returns 级别
When selecting "top n" columns from data.table or head(), R returns levels from underlying vector
我有一个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
...等等
我知道如何使用几种方法 select 前 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
或将 aggregate
与 order
和 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
我的问题是,在此之后,我一直在尝试制作前 4 个 taxon_name
的矢量列表 - 但每次我都尝试这样做(即 toptaxa <- top4d$taxon_name
) 它从我的钓鱼数据集中吐出了所有 67 个原始分类群!最初我认为这是 data.table
的一个设计特性,但看到无论我使用什么方法都会发生这种情况,很明显我没有正确理解它。
之前也有人问过类似的问题(例如 Why does selecting column(s) from a data.table results in a copy?),但我不确定我是否看到了让我 select 仅从我的结果中得到的答案。我怎样才能只操纵我的前 4 排序的结果?
编辑 这是我的数据集:https://www.dropbox.com/s/izn7sdpeosvg1nj/discards_for_stack.csv?dl=0
使用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)
我使用 data.table
的方法如下。我正在使用 data.table::CJ
生成少数 taxon_name
选项和 5 年序列的笛卡尔连接,然后随机填充 amount
。
library(data.table)
set.seed(1234)
DT <- CJ(year = seq.int(1950L,1954L,1L),
taxon_name = c("Gadus morhua","Sebastes","Melanogrammus aeglefinus",
"Reinhardtius hippoglossoides","Foo","Bar","Baz"))
DT[, amount := sample.int(100, .N)]
setkey(DT,taxon_name)
print(DT[sample(.N,5)])
# year taxon_name amount
# 1: 1951 Reinhardtius hippoglossoides 25
# 2: 1951 Baz 99
# 3: 1953 Baz 13
# 4: 1951 Sebastes 81
# 5: 1950 Reinhardtius hippoglossoides 97
Top4 <- DT[,.(amount = sum(amount)), by = .(taxon_name)][order(-amount)][1:4,taxon_name]
print(Top4)
# [1] "Sebastes" "Baz" "Melanogrammus aeglefinus" "Gadus morhua"
我有一个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
...等等
我知道如何使用几种方法 select 前 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
或将 aggregate
与 order
和 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
我的问题是,在此之后,我一直在尝试制作前 4 个 taxon_name
的矢量列表 - 但每次我都尝试这样做(即 toptaxa <- top4d$taxon_name
) 它从我的钓鱼数据集中吐出了所有 67 个原始分类群!最初我认为这是 data.table
的一个设计特性,但看到无论我使用什么方法都会发生这种情况,很明显我没有正确理解它。
之前也有人问过类似的问题(例如 Why does selecting column(s) from a data.table results in a copy?),但我不确定我是否看到了让我 select 仅从我的结果中得到的答案。我怎样才能只操纵我的前 4 排序的结果?
编辑 这是我的数据集:https://www.dropbox.com/s/izn7sdpeosvg1nj/discards_for_stack.csv?dl=0
使用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)
我使用 data.table
的方法如下。我正在使用 data.table::CJ
生成少数 taxon_name
选项和 5 年序列的笛卡尔连接,然后随机填充 amount
。
library(data.table)
set.seed(1234)
DT <- CJ(year = seq.int(1950L,1954L,1L),
taxon_name = c("Gadus morhua","Sebastes","Melanogrammus aeglefinus",
"Reinhardtius hippoglossoides","Foo","Bar","Baz"))
DT[, amount := sample.int(100, .N)]
setkey(DT,taxon_name)
print(DT[sample(.N,5)])
# year taxon_name amount
# 1: 1951 Reinhardtius hippoglossoides 25
# 2: 1951 Baz 99
# 3: 1953 Baz 13
# 4: 1951 Sebastes 81
# 5: 1950 Reinhardtius hippoglossoides 97
Top4 <- DT[,.(amount = sum(amount)), by = .(taxon_name)][order(-amount)][1:4,taxon_name]
print(Top4)
# [1] "Sebastes" "Baz" "Melanogrammus aeglefinus" "Gadus morhua"