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

时间:2017-10-19 01:36:09

标签: r 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))

我需要创建一个数据框,将因子site的级别转换为变量。因此,site1site2将成为变量,这些变量中的数据将是这些网站abun级别的genus值。由于并非所有站点都具有相同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函数,无法获得所需的输出,也不知道如何获取零来填充空数据。

1 个答案:

答案 0 :(得分:0)

由于您希望每个组中的索引都是并行的,因此可以为每个组设置一个索引,您可以使用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有多个值,则会失败,并且您必须创建一个更唯一的标识符列。