Freitag, 29. Mai 2009

Kombinationen tabellieren

Ausgangslage ist ein data.frame mit einer Zeile pro Element und n Indikatorvariablen. Es stellt sich die Frage nach den Häufigkeiten der Kombinationen der Indikatorvariablen.

d.frm <- data.frame(name=c("Franz", "Maria", "Claudine")
  , A=c(1,0,1), B=c(1,1,1), C=c(0,0,1), D=c(0,1,0))

Solution 1 (clumsy):

# Berechne die Summe der mit einer 2er-Potenz multiplizierten Indikatoren
d.frm$sum <- as.matrix(d.frm[,2:5]) %*% (2^(0:3))

# Erzeuge levels für eine Komb-Faktor
d.lvl <- expand.grid( c(0,"A"),c(0,"B"),c(0,"C"),c(0,"D") )

# Bilde eine neue Variable mit der Textbezeichnung der 2^n-Summe
d.frm$sum_x <- factor(d.frm$sum
  , levels=((d.lvl!=0)*1) %*% (2^(0:3))
  , labels=gsub( "0","", do.call( "paste", c( d.lvl, list(sep="") ))))

d.frm
......name A B C D sum sum_x
1 ...Franz 1 1 0 0 ..3 ...AB
2 ...Maria 0 1 0 1 .10 ...BD
3 Claudine 1 1 1 0 ..7 ..ABC

Solution 2 (smart):

d.frm$sum_xx <- apply( d.frm[,2:5], 1,
  function(x) paste(LETTERS[1:4][as.logical(x)], collapse="") )


Wenn einfach nur die Kombinationen gesucht sind, gibt's dafür die Bordmittel:

> combn( letters[1:4], 2 )
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] "a" "a" "a" "b" "b" "c"
[2,] "b" "c" "d" "c" "d" "d"

Oder auch interessant mit den Funktionen outer und lower.tri (pairwise):

m <- outer(x, x, paste, sep="-" )
m[!lower.tri(m, diag=TRUE) ]

[1] "a-b" "a-c" "b-c" "a-d" "b-d" "c-d"

Get all binary combinations
The idea is to get a vector with n 0s and n 1s, chop it into n parts of c(0,1) (this is a list), and use expand.grid:

n <- 4="4">
expand.grid(split(rep(c(0,1), each=n), 1:n))

Keine Kommentare: