2017-08-30 3 views
3

Ich habe einen Datenrahmen, der eine Reihe von Daten enthält, die in bestimmten Elementen der Zeilen mit Kommas verbunden ist. Etwas, das wie folgt aussieht: in einer Form erhalten möchteAggregation mehrerer Spalten aus Datenrahmen

df <- data.frame(
c(2012,2012,2012,2013,2013,2013,2014,2014,2014) 
,c("a,b,c","d,e,f","a,c,d,c","a,a,a","b","c,a,d","g","a,b,e","g,h,i") 
) 
names(df) <- c("year", "type") 

ich es, dass dcast Nähe ist es darum geht, zu, mit dem Jahr, a, b, c, etc. die Spalten zu sein, und die Frequenz über die Daten Rahmen, der in den Zellen des resultierenden Datenrahmens ist. Ich habe zuerst versucht, colsplit auf df zu tun und dann dcast nach, aber das scheint nur zu funktionieren, wenn ich auf einer der Ebenen aggregieren will statt alle.

df2 <- data.frame(df$year, colsplit(df$type, ',' , c('v1','v2','v3','v4','v5'))) 
df3 <- dcast(df2, df.year ~ v1) 

Dieses Ergebnis gibt mir nur für die erste Ebene der colsplit, statt sie alle. Bin ich nah an einer Lösung oder sollte ich einen anderen Ansatz verwenden?

Antwort

0

Vielleicht könnte so etwas funktionieren?

# extract unique values and years 
    vals <- unique(do.call(c, strsplit(x = as.vector(df$type), "[[:punct:]]"))) 
    years <- unique(df$year) 

# count 
    df4 <- data.frame(sapply(vals, (function(vl) {sapply(years, (function(ye){ 
     sum(do.call(c, strsplit(as.vector(df$type[df$year == ye]) , "[[:punct:]]")) == vl) 
    }))}))) 
    df4 <- cbind(years, df4) 
    df4 
#result 
    years a b c d e f g h i 
1 2012 2 1 3 2 1 1 0 0 0 
2 2013 4 1 1 1 0 0 0 0 0 
3 2014 1 1 0 0 1 0 2 1 1 
1

Sie sind nah an der Lösung. Du brauchst nur noch einen Schritt. Sie müssen melt alle Werte in einer Spalte vor dcast. Siehe das Beispiel.

require(reshape2) 

df <- data.frame(c(2012,2012,2012,2013,2013,2013,2014,2014,2014), 
       c("a,b,c","d,e,f","a,c,d,c","a,a,a","b","c,a,d","g","a,b,e","g,h,i")) 
names(df) <- c("year", "type") 
df 

df2 <- data.frame(df$year, colsplit(df$type, ',', c('v1','v2','v3','v4','v5'))) 
df2 

df3 <- melt(df2, id.vars = "df.year", na.rm = T) 
df3 

df4 <- dcast(df3[df3$value != "", ], df.year ~ value, fun.aggregate = length) 
df4 
3

Hier ist eine einzige Zeile Option ist mit base R durch die ‚Typen‘ Spalte mit strsplit Aufspalten und stellen Sie dann die Namen der list Ausgabe als ‚Jahr‘, stack es zu einem einzigen data.frame und die Frequenz erhalten zählen table

table(stack(setNames(strsplit(as.character(df$type), ","), df$year))[2:1]) 
#  values 
#ind a b c d e f g h i 
# 2012 2 1 3 2 1 1 0 0 0 
# 2013 4 1 1 1 0 0 0 0 0 
# 2014 1 1 0 0 1 0 2 1 1 
1

hier ein data.table Ansatz:

library(data.table) 
setDT(df) 
dcast(df[, .(unlist(strsplit(as.character(type), ",", fixed=TRUE))), by = year], 
year ~ V1, value.var = "V1", fun.aggregate = length) 
# year a b c d e f g h i 
#1: 2012 2 1 3 2 1 1 0 0 0 
#2: 2013 4 1 1 1 0 0 0 0 0 
#3: 2014 1 1 0 0 1 0 2 1 1 

Wir f Trennen Sie zuerst die Spalte Typ durch Komma und pro Jahr-Gruppe auf ein langes Format, dann dcast zu weit mit der length als Aggregat-Funktion.

Verwandte Themen