tidyr:转置变量并用零填充空白

tidyr: transpose variables and fill blanks with zeros

我有一个这样的数据框:

set.seed(456)
df <- data.frame(site = c(rep("Site1", 10), rep("Site2", 9)), 
                 genus = c(rep("sp1", 5), rep("sp2", 5), rep("sp1", 5), rep("sp2", 2), rep("sp3", 2)), 
                 abun = rnorm(19, 10,1))

我需要制作一个数据框,将因子 site 的水平转换为变量。因此,site1site2 将成为一个变量,这些变量中的数据将是这些站点的 genus 级别的 abun 值。由于并非所有站点都具有相同的 genus 或相同数量的该属个体,因此那些没有物种或这些物种的代表很少的站点将用零填充。

本例中的数据将显示为:

output<- data.frame(genus = c(rep("sp1", 5), rep("sp2", 5), rep("sp3", 2)), 
                    site1 = c(9,22,74,86,79, 34,9,29,24,39,0,0), 
                    site2 = c(38,22,76,83,60, 66,85,0,0,0, 46,72)) 

我已经尝试了各种版本的 tidyverse mutate 或 reshape 函数,但无法获得所需的输出,也不知道如何获取零来填充空数据。

由于您希望索引在每个组中是平行的,因此为每个组设置一个索引,您可以使用 dplyr::group_byrow_number 来完成,之后展开将正常工作:

library(tidyverse)
set.seed(456)

df<- data.frame( site= c(rep("Site1", 10), rep("Site2", 9)), 
                 genus= c(rep("sp1", 5), rep("sp2", 5), rep("sp1", 5), rep("sp2", 2), rep("sp3", 2) ), 
                 abun= rnorm(19, 10,1))

df %>% 
    group_by(site) %>% 
    mutate(i = row_number()) %>%    # add row indices for each group
    spread(site, abun, fill = 0)
#> # A tibble: 12 x 4
#>     genus     i     Site1     Site2
#>  * <fctr> <int>     <dbl>     <dbl>
#>  1    sp1     1  8.656479  9.084189
#>  2    sp1     2 10.621776 11.311097
#>  3    sp1     3 10.800875 10.988726
#>  4    sp1     4  8.611108 11.653929
#>  5    sp1     5  9.285643  8.559195
#>  6    sp2     6  9.675939 11.947356
#>  7    sp2     7 10.690643 11.736936
#>  8    sp2     8 10.250548  0.000000
#>  9    sp2     9 11.007352  0.000000
#> 10    sp2    10 10.573235  0.000000
#> 11    sp3     8  0.000000 10.387483
#> 12    sp3     9  0.000000 12.280034

如果给定 igenus 有多个值,这将失败,您必须创建一个更独特的标识符列。