La documentation de tidyr suggère que la collecte et la propagation sont transitives, mais l'exemple suivant avec les données "iris" montre qu'elles ne le sont pas, mais on ne sait pas pourquoi. Toute clarification serait grandement appréciée
iris.df = as.data.frame(iris)
long.iris.df = iris.df %>% gather(key = feature.measure, value = size, -Species)
w.iris.df = long.iris.df %>% spread(key = feature.measure, value = size, -Species)
Je m'attendais à ce que la trame de données "w.iris.df" soit identique à "iris.df", mais j'ai reçu l'erreur suivante:
"Erreur: identificateurs en double pour les lignes (1, 2, 3, 4, 5, 6, 7, 8, 9 ..."
Ma question générale est de savoir comment inverser une application de "rassembler" sur ce type de jeu de données.
L’intervention de Hadley était sans surprise parfaite ... mais j’ai fini par modifier la syntaxe un peu plus tard ... alors, pour ce que ça vaut, je publie le code entièrement opérationnel (désolée, ma syntaxe est un peu différente de celle ci-dessus):
library(tidyr)
library(dplyr)
wide <-
iris %>%
mutate(row = row_number()) %>%
gather(vars, val, -Species, -row) %>%
spread(vars, val)
head(wide)
# Species row Petal.Length Petal.Width Sepal.Length Sepal.Width
# 1 setosa 1 1.4 0.2 5.1 3.5
# 2 setosa 2 1.4 0.2 4.9 3.0
# 3 setosa 3 1.3 0.2 4.7 3.2
# 4 setosa 4 1.5 0.2 4.6 3.1
# 5 setosa 5 1.4 0.2 5.0 3.6
# 6 setosa 6 1.7 0.4 5.4 3.9
head(iris)
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1 5.1 3.5 1.4 0.2 setosa
# 2 4.9 3.0 1.4 0.2 setosa
# 3 4.7 3.2 1.3 0.2 setosa
# 4 4.6 3.1 1.5 0.2 setosa
# 5 5.0 3.6 1.4 0.2 setosa
# 6 5.4 3.9 1.7 0.4 setosa
Ils sont les mêmes .... il suffit de réorganiser si vous en avez envie ...
wide <- wide[,c(3, 4, 5, 6, 1)] ## Reorder and then remove "row" column
et fait.
Comme la réponse précédente n’était peut-être pas suffisamment claire, la façon dont vous exécutez gather
pose un problème qui apparaît lorsque vous essayez de modifier spread
.
Le problème est qu’au cours du processus de collecte, vous perdez la trace de ce que feature.measure
appartient à quelle ligne du cadre de données original, de sorte que spread
n’a aucune idée de la manière de combiner à nouveau des valeurs individuelles dans la table "large".
iris.df = as.data.frame(iris)
long.iris.df = iris.df %>%
tibble::rowid_to_column() %>%
gather(key = feature.measure, value = size, -Species, -rowid)
#> rowid Species feature.measure size
#> 1 1 setosa Sepal.Length 5.1
#> 2 2 setosa Sepal.Length 4.9
#> 3 3 setosa Sepal.Length 4.7
#> 4 4 setosa Sepal.Length 4.6
#> 5 5 setosa Sepal.Length 5.0
#> 6 6 setosa Sepal.Length 5.4
Désormais, chaque valeur de size
conserve sa rowid
afin que vous puissiez toujours la recombiner dans le jeu de données étendu (en supprimant rowid
inutile):
w.iris.df = long.iris.df %>%
spread(key = feature.measure, value = size) %>%
select(-rowid)
head(w.iris.df)
#> Species Petal.Length Petal.Width Sepal.Length Sepal.Width
#> 1 setosa 1.4 0.2 5.1 3.5
#> 2 setosa 1.4 0.2 4.9 3.0
#> 3 setosa 1.3 0.2 4.7 3.2
#> 4 setosa 1.5 0.2 4.6 3.1
#> 5 setosa 1.4 0.2 5.0 3.6
#> 6 setosa 1.7 0.4 5.4 3.9