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
的水平转换为变量。因此,site1
和 site2
将成为一个变量,这些变量中的数据将是这些站点的 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_by
和 row_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
如果给定 i
和 genus
有多个值,这将失败,您必须创建一个更独特的标识符列。
我有一个这样的数据框:
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
的水平转换为变量。因此,site1
和 site2
将成为一个变量,这些变量中的数据将是这些站点的 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_by
和 row_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
如果给定 i
和 genus
有多个值,这将失败,您必须创建一个更独特的标识符列。