2017-05-14 4 views
0

j'ai cet ensemble de données appelé « donnéesEntrée »données Remodeler basées sur des colonnes différentes

Country Unknown Male Female Affected Male Female Unaffected Male Female 
USA  200 120 80  130  80 50  70  40 30 
AU  140 80 60  60  30 30  80  50 30 

Et je vais avoir deux ensembles de données de sortie et seront comme ceux ci-dessous, comme vous pouvez le voir, l'ensemble de données d'entrée a 3 catégories ici comme mentionné dans les noms de colonnes 2,5,8.

Dans l'ensemble de données de sortie 1, la colonne Catégorie a des catégories qui sont les noms de colonne dans les données d'entrée. Ensuite, le pays de la colonne pays et la colonne Homme auront la valeur de la colonne Homme dans l'entrée.

De même, dans l'ensemble de données de sortie 2, la catégorie et le pays restent les mêmes, mais les données réelles de la 3e colonne doivent avoir une valeur dans les catégories correspondantes de l'entrée, colonnes 2,5,8.

La clé ici est que la structure de l'ensemble de données en entrée reste la même.

Output 1 

Category Country Male 
Unknown  USA  120 
Affected  USA  80 
Unaffected USA  40 
. 
. 
. 

Output 2 

Category Country Actuals 
Unknown  USA  200 
Affected  USA  130 
Unaffected USA  70 
. 
. 
. 

Alors ce que je faisais maintenant, en utilisant une boucle de sous-ensemble toutes les catégories de l'ensemble de données d'entrée en utilisant les indices -

Par exemple, en utilisant inputdata[,c(1,i)] et ma variable 'i' sera 3,6,9 for output 1 et 2,5,8 for output 2. Puis créé une liste de trames de données (une pour chaque catégorie) et les a combinées ensemble pour chaque sortie. Je me demande simplement s'il y a un autre moyen de le faire pour le rendre efficace.

EDIT: - Ajout mon code tel que demandé,

for(i in seq(3, 9, by=3)) { 
    if(!exists('mylist')) mylist <- NULL 
    output1 <- inputdata[,c(1,i)] 
    if(i==3) { 
     output1$category <- 'unknown' 
    } else if (i==6) { 
     output1$category <- 'affected' 
    } else 
     output1$category <- 'unaffected' 
    mylist <- c(mylist,output1) 
    rm(output1) 
    } 


    for(i in seq(2, 8, by=3)) { 
     if(!exists('mylist')) mylist <- NULL 
     output2 <- inputdata[,c(1,i)] 
     if(i==3) { 
      output2$category <- 'unknown' 
     } else if (i==6) { 
      output2$category <- 'affected' 
     } else 
      output2$category <- 'unaffected' 
     mylist <- c(mylist,output2) 
     rm(output2) 
     } 

S'il vous plaît laissez-moi savoir s'il y a quelque chose pas clair.

+0

S'il vous plaît poster le code que vous avez essayé. – Sotos

+0

Ajouté ici. :) –

+0

Mais vous avez des colonnes avec le même nom. Les noms de colonne doivent être uniques. Pouvez-vous charger cette table dans R en tant que data.frame en gardant ces noms de colonnes? – Osdorp

Répondre

0

Voici une méthode de base R qui utilise stack pour convertir en long sur la base de colonnes spécifiques (c'est-à-dire mâle/femelle, catégorie).

#data frame of categories - You can further split of country if needed 
# by split(d1, d1$country) 

d1 <- data.frame(stack(df[-1][c(T, F, F)]), country = df$Country, stringsAsFactors = FALSE) 

# values  ind country 
#1 200 Unknown  USA 
#2 140 Unknown  AU 
#3 130 Affected  USA 
#4  60 Affected  AU 
#5  70 Unaffected  USA 
#6  80 Unaffected  AU 

#create a list with two data frames (male and female) 
#To split by country again, then lapply(l1, function(i) split(i, i$country)) 

l1 <- lapply(c('Male', 'Female'), function(i) setNames(data.frame(d1$ind, 
               stack(df[grepl(i, names(df))])[-2], 
                df$Country, stringsAsFactors = F), 
               c('category', i, 'country'))) 

#[[1]] 
# category Male country 
#1 Unknown 120  USA 
#2 Unknown 80  AU 
#3 Affected 80  USA 
#4 Affected 30  AU 
#5 Unaffected 40  USA 
#6 Unaffected 50  AU 

#[[2]] 
# category Female country 
#1 Unknown  80  USA 
#2 Unknown  60  AU 
#3 Affected  50  USA 
#4 Affected  30  AU 
#5 Unaffected  30  USA 
#6 Unaffected  30  AU 

DONNÉES

dput(df) 
structure(list(Country = c("USA", "AU"), Unknown = c(200L, 140L 
), Male = c(120L, 80L), Female = c(80L, 60L), Affected = c(130L, 
60L), Male.1 = c(80L, 30L), Female.1 = c(50L, 30L), Unaffected = c(70L, 
80L), Male.2 = c(40L, 50L), Female.2 = c(30L, 30L)), .Names = c("Country", 
"Unknown", "Male", "Female", "Affected", "Male.1", "Female.1", 
"Unaffected", "Male.2", "Female.2"), row.names = c(NA, -2L), class = "data.frame") 
+0

Merci. Cela fonctionne parfaitement. –