2016-10-12 1 views
0

Je suis bloqué par le problème de résolution de données suivant. Chaque jeu de données a plusieurs valeurs de aValue pour une valeur de aName. Cela peut être facilement représenté dans un cadre de données propre. Je souhaite "étaler" la variable de l'ensemble de données dans des colonnes individuelles. (Je ne suis pas en mesure d'utiliser tidyr::spread pour créer une sortie souhaitée en raison des clés en double.)Répartition des paires de valeurs clés dans les colonnes

### 
# Desired output 
### 
# aName ds1 ds2 ds3 
# a  1 10 100 
# a  2 20 NA 
# a  3 30 NA 
# b  4 40 NA 
# b  5 NA NA 
# c  NA 50 200 
# c  NA 60 300 
# c  NA NA 400 

est-il un moyen bien rangé pour générer la sortie désirée?

ps: Je suis au courant de spread-key-value-pairs-when-keys-are-in-different-columns question, mais la solution

dcast(melt(someDatasets, id = "aName", na.rm = TRUE), aName~value) 

ne produit pas le résultat souhaité, car une fonction d'agrégation length est utilisée.

+0

Où est la longueur utilisée et pourquoi est-ce pas souhaitable? –

+1

Peut-être 'bind_rows (certainsDatasets)%>% group_by (jeu de données)%>% mute (aName = paste0 (aName, 1: n()))%>% spread (jeu de données, aValue)%>% mute (aName = substr (aName, 1, 1)) ». – lukeA

+2

Ajoutez un ID secondaire basé sur le regroupement de "aName" et "dataset" (à partir de votre jeu de données "tidyData"), puis utilisez 'dcast'. Par exemple, si vous avez nommé l'ID secondaire "ID", vous pouvez faire 'dcast (tidyDataWithID, aName + ID ~ jeu de données, value.var =" aValue ")'. – A5C1D2H2I1M1N2O1R2T1

Répondre

2

Comme indiqué dans les commentaires par @lukeA et @A Handcart et Mohair, vous pouvez ajouter un ID supplémentaire à vos données pour éviter le problème touches en double.

library(dplyr) 
library(tidyr) 

tidyData = bind_rows(someDatasets) %>% 
    group_by(dataset, aName) %>% 
    mutate(id = paste0(aName, 1:n())) %>% 
    ungroup() %>% 
    select(-aName) 

# head(tidyData) 
# Source: local data frame [6 x 3] 
# 
# aValue dataset id 
# <dbl> <chr> <chr> 
# 1  1  ds1 a1 
# 2  2  ds1 a2 
# 3  3  ds1 a3 
# 4  4  ds1 b1 
# 5  5  ds1 b2 
# 6  10  ds2 a1 

id est maintenant unique au sein de chaque groupe (ensemble de données) afin que nous puissions procéder à la diffusion:

tidyData %>% 
    spread(dataset, aValue) %>% 
    mutate(id = substr(id, 1, 1)) 

# Source: local data frame [10 x 4] 
# 
#  id ds1 ds2 ds3 
# <chr> <dbl> <dbl> <dbl> 
# 1  a  1 10 100 
# 2  a  2 20 NA 
# 3  a  3 30 NA 
# 4  b  4 40 NA 
# 5  b  5 NA NA 
# 6  c NA 50 200 
# 7  c NA 60 300 
# 8  c NA NA 400 
+0

Merci. La deuxième sortie est basée sur des valeurs non uniques 'aValue's et' tidyData%>% groupe_by (aName, ensemble de données)%>% mute (ID = 1: n())%>% dégrouper()%>% tidyr :: unite (col = "nom", aName, ID, sep = "#")%>% tidyr :: spread (ensemble de données, aValue)%>% tidyr :: separate (col = "aName", into = c ("aName", "ID"), supprimer = T, sep = "#")%>% dplyr :: select (- ID) 'a fait le travail. J'ai l'impression que la version 'tidyr' est plus verbeuse que celle de 'reshape2' - c'est malheureux. – Drey

+0

@Drey Désolé, j'ai oublié de mettre à jour la partie supérieure du code - voir maintenant (un peu moins verbeux ...) – jakub

+0

en rappelant 'unite' et' séparé' rend en effet plus lisible. Merci encore et encore aux autres. – Drey