2017-05-14 6 views
0

Ich habe diesen Datensatzumformen Daten basierend auf verschiedene Spalten

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 

‚Eingangsdaten‘ genannt und ich werde zwei Ausgangsdatenmengen hat, und es wird, wie die unten diejenigen sein, wie Sie sehen können, der Eingabedatensatz hat 3 Kategorien hier wie in den Spaltennamen 2,5,8 erwähnt.

Im Datensatz der Ausgabe 1 enthält die Spalte Kategorie die Spaltennamen in den Eingabedaten. Dann wird das Land aus der Länderspalte und der Male-Spalte einen Wert aus der Male-Spalte in der Eingabe haben.

Ähnlich wie in der Ausgabe 2 Datensatz, Kategorie und Land bleibt gleich, aber die 3. Spalte Actuals sollte Wert aus den entsprechenden Kategorien in der Eingabe, Spalten 2,5,8 haben.

Der Schlüssel hier ist, dass die Eingabe-Dataset-Struktur gleich bleibt.

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

Also, was ich jetzt ist auch noch ein for-Schleife jede Kategorie aus dem Eingabedatensatz der Teilmenge der Indizes mit -

Zum Beispiel inputdata[,c(1,i)] und meinen 'i' Variable wird 3,6,9 for output 1 und 2,5,8 for output 2 sein. Dann erstellte er eine Liste von Datenrahmen (einen für jede Kategorie) und kombinierte sie für jeden Ausgang. Ich frage mich nur, ob es andere Wege gibt, wie ich das machen kann, um es effizient zu machen.

EDIT: - Hinzufügen von meinem Code wie gewünscht,

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

Bitte lassen Sie mich wissen, ob es etwas unklar ist.

+0

Bitte senden Sie den Code, den Sie versucht. – Sotos

+0

Hinzugefügt hier. :) –

+0

Aber Sie haben Spalten mit dem gleichen Namen. Spaltennamen müssen eindeutig sein. Können Sie diese Tabelle in R als data.frame laden, wobei diese Spaltennamen beibehalten werden? – Osdorp

Antwort

0

Hier ist eine Basis-R-Methode, die stack verwendet, um basierend auf bestimmten Spalten zu konvertieren (d. H. Männlich/weiblich, Kategorie).

#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 

DATA

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

Danke. Das funktioniert perfekt. –

Verwandte Themen