我的数据集包括多种植物(基因型)的植物观察结果 环境。此示例数据包含每个观察的一行 我有。它列出了植物基因型和观察的环境 是的。
nObs <- 500
data <- tibble(Gt = sample(sprintf("%02d",1:20),nObs,T),
Env = sample(LETTERS\[1:8\],nObs,T)
# The measured plant trait would also go here but is irrelevant for now.
)
我想要的是一张表格,它显示了我在多少环境中的每种基因型
它重复了多少次。例如,如果我的基因型01
有两次重复
在五个环境中,但在另外两个环境中只有一个,即输出
我期待的是:
Genotype nRepl nEnv
---------------------
A 2 5
A 1 2
我找到了使用do
的可能性,但由于do
期望它很慢
为每个包含摘要信息的数据子组创建的数据帧。这创造了很多
开销,正如您在分析时所看到的那样:
profvis::profvis(for(1:10) idea1()) #idea1 is defined below
是否有其他方法,可能没有使用do(.)
,这会给出这个结果?
到目前为止,我的想法如下所示:
这将返回每个基因型中每个基因型的观察次数 环境(=复制):
data %>% count(Gt, Env)
## # A tibble: 158 x 3
## Gt Env n
## <chr> <chr> <int>
## 1 01 A 2
## 2 01 B 1
## 3 01 C 2
## 4 01 D 2
## 5 01 E 6
## 6 01 F 4
## 7 01 G 5
## 8 01 H 3
## 9 02 A 1
## 10 02 B 2
## # ... with 148 more rows
到目前为止,这是我能提出的三种方法。全部使用do
:
idea1 <- function(){
data %>% count(Gt, Env) %>% group_by(Gt) %>%
do({
t <- table(.$n)
tibble(nRpl = names(t), nEnv = as.integer(t))
})
}
idea2 <- function(){
data %>% count(Gt, Env) %>% group_by(Gt) %>%
do({
t <- table(.$n)
data.frame(nRpl = names(t), nEnv = as.integer(t), stringsAsFactors = FALSE)
})
}
idea3 <- function(){
data %>% count(Gt, Env) %>% group_by(Gt) %>%
do({
t <- table(.$n)
data.frame(nRpl = names(t), nEnv = as.integer(t), stringsAsFactors = FALSE,
check.names = FALSE, check.rows = FALSE)
})
}
这是我想要的输出:
idea1()
## # A tibble: 93 x 3
## # Groups: Gt [20]
## Gt nRpl nEnv
## <chr> <chr> <int>
## 1 01 1 1
## 2 01 2 3
## 3 01 3 1
## 4 01 4 1
## 5 01 5 1
## 6 01 6 1
## 7 02 1 1
## 8 02 2 4
## 9 02 4 1
## 10 02 6 1
## # ... with 83 more rows
速度比较:
library(microbenchmark)
microbenchmark({idea1()},{idea3()},{idea4()}, times = 20)
## Unit: milliseconds
## expr min lq mean median uq max
## { idea1() } 299.21640 373.87930 435.2567 427.8721 460.7488 693.9279
## { idea3() } 80.03300 100.25709 144.8413 124.8140 182.9211 300.3150
## { idea4() } 83.04371 98.18572 122.6464 108.1945 141.0208 216.3999
## neval
## 20
## 20
## 20
答案 0 :(得分:1)
您可以使用count
两次,第二次计算第一次计算的复制次数:
library(dplyr)
set.seed(47) # for sampling reproducibility
data <- tibble(Gt = sample(sprintf("%02d", 1:20), 500, replace = TRUE),
Env = sample(LETTERS[1:8], 500, replace = TRUE))
data %>%
count(Gt, Env) %>%
count(Gt, n) %>%
rename(nRpl = n, nEnv = nn) # make better names
#> # A tibble: 85 x 3
#> Gt nRpl nEnv
#> <chr> <int> <int>
#> 1 01 2 1
#> 2 01 3 4
#> 3 01 4 3
#> 4 02 2 1
#> 5 02 3 1
#> 6 02 4 3
#> 7 02 6 1
#> 8 03 1 3
#> 9 03 2 1
#> 10 03 3 1
#> # ... with 75 more rows