2017-10-19 11 views
1

J'ai un dataframe comme ceci:tidyr: transposent des variables et remplir des blancs avec des zéros

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)) 

que je dois faire une trame de données qui convertit les niveaux du facteur site aux variables. Ainsi, site1 et site2 deviendraient une variable et les données dans ces variables seraient les abun valeurs pour genus niveaux à ces sites. Puisque tous les sites n'auront pas le même genus ou le même nombre d'individus de ce genre, les sites sans espèce ou avec peu de représentants de ces espèces seraient remplis de zéros.

Les données dans cet exemple apparaîtraient comme:

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)) 

J'ai essayé différentes versions de tidyverse muter ou remodeler les fonctions, et ne peuvent pas obtenir la sortie désirée et je ne sais comment obtenir les zéros pour remplir les données vides.

Répondre

0

Puisque vous voulez que les indices soient parallèles dans chaque groupe, mis en place un indice pour chacun, que vous pouvez faire avec dplyr::group_by et row_number, après quoi la diffusion fonctionnera correctement:

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 

Si vous avoir plusieurs valeurs pour un i donné et genus, cela échouera, et vous devrez faire une colonne d'identifiant plus unique.

+0

@ C8H10N4O2 Non, cela vous donne un data.frame différent avec le même nombre de lignes que 'df' (19), pas le 12 de' output'. – alistaire

+0

ok, je l'ai maintenant. – C8H10N4O2

+0

Merci! Cela fonctionne très bien. Le problème que j'avais, mais qui était capable de résoudre de manière inefficace, était le problème avec les variables 'Site1' et' Site2' devenant des facteurs, le fill = 0 ne fonctionnait pas. J'ai donc utilisé la fonction as.numeric sur chaque variable et ai changé toutes les NA à 0. y a-t-il un moyen de résoudre ce problème dans les fonctions de tidyr? – Danielle