R kullanarak “paralel kümeler” grafiği oluşturmak mümkün müdür?


16

Tormod sorusu ( burada yayınlanan ) sayesinde Paralel Kümeler grafiğine rastladım . İşte nasıl göründüğüne bir örnek: resim açıklamasını buraya girin (Titanik veri kümesinin bir görselleştirmesidir. Örneğin, hayatta kalamayan kadınların çoğunun üçüncü sınıfa ait olduğunu gösteren ...)

R ile böyle bir komplo üretebilmek isterdim. Bunu yapmak mümkün mü?

Teşekkürler, Tal


1
Grafiklerle ilgili fikirler için her zaman R grafik galerisine bakarım. İşte oradan biraz istediğin şeye benzeyen bir şey: R Graph Gallery paralel . Etiket bulutunda paralel tıklatarak buldum, ancak daha iyi seçenekler olabilir.
Nick Sabbe

1
Teşekkürler Nick. Ancak bu, kodda büyük bir değişiklik yapmadan kategorik veriler için işe yaramayacaktır (muhtemelen bunu inşa etmek için en iyi işlevler tabanı değildir). Umarım birisi zaten benzer bir şey yapmış olabilir ...
Tal Galili

Yanıtlar:


25

Hadley'nin yorumu sayesinde sadece temel grafikleri kullanan bir sürüm. (Önceki sürüm için düzenleme geçmişine bakın).

üçüncü deneme

parallelset <- function(..., freq, col="gray", border=0, layer, 
                             alpha=0.5, gap.width=0.05) {
  p <- data.frame(..., freq, col, border, alpha, stringsAsFactors=FALSE)
  n <- nrow(p)
  if(missing(layer)) { layer <- 1:n }
  p$layer <- layer
  np <- ncol(p) - 5
  d <- p[ , 1:np, drop=FALSE]
  p <- p[ , -c(1:np), drop=FALSE]
  p$freq <- with(p, freq/sum(freq))
  col <- col2rgb(p$col, alpha=TRUE)
  if(!identical(alpha, FALSE)) { col["alpha", ] <- p$alpha*256 }
  p$col <- apply(col, 2, function(x) do.call(rgb, c(as.list(x), maxColorValue = 256)))
  getp <- function(i, d, f, w=gap.width) {
    a <- c(i, (1:ncol(d))[-i])
    o <- do.call(order, d[a])
    x <- c(0, cumsum(f[o])) * (1-w)
    x <- cbind(x[-length(x)], x[-1])
    gap <- cumsum( c(0L, diff(as.numeric(d[o,i])) != 0) )
    gap <- gap / max(gap) * w
    (x + gap)[order(o),]
  }
  dd <- lapply(seq_along(d), getp, d=d, f=p$freq)
  par(mar = c(0, 0, 2, 0) + 0.1, xpd=TRUE )
  plot(NULL, type="n",xlim=c(0, 1), ylim=c(np, 1),
       xaxt="n", yaxt="n", xaxs="i", yaxs="i", xlab='', ylab='', frame=FALSE)
  for(i in rev(order(p$layer)) ) {
     for(j in 1:(np-1) )
     polygon(c(dd[[j]][i,], rev(dd[[j+1]][i,])), c(j, j, j+1, j+1),
             col=p$col[i], border=p$border[i])
   }
   text(0, seq_along(dd), labels=names(d), adj=c(0,-2), font=2)
   for(j in seq_along(dd)) {
     ax <- lapply(split(dd[[j]], d[,j]), range)
     for(k in seq_along(ax)) {
       lines(ax[[k]], c(j, j))
       text(ax[[k]][1], j, labels=names(ax)[k], adj=c(0, -0.25))
     }
   }           
}

data(Titanic)
myt <- subset(as.data.frame(Titanic), Age=="Adult", 
              select=c("Survived","Sex","Class","Freq"))
myt <- within(myt, {
  Survived <- factor(Survived, levels=c("Yes","No"))
  levels(Class) <- c(paste(c("First", "Second", "Third"), "Class"), "Crew")
  color <- ifelse(Survived=="Yes","#008888","#330066")
})

with(myt, parallelset(Survived, Sex, Class, freq=Freq, col=color, alpha=0.2))

Aaron, vay, harika cevap - Keşke V'yi iki kez işaretleyebilseydim. Teşekkür ederim!
Tal Galili

2
Beğendiğine sevindim. Eğlenceliydi. :) Tek zor bölüm çubukların başlayıp bitmesi gereken yerleri getpalmaktır (ki bu alt fonksiyondadır); gerisi sadece çokgen çiziyor.
Aaron Stack Overflow'dan ayrıldı

1
Sadece başka bir panel.textsatır. Bkz. Düzenleme.
Aaron Stack Overflow'dan ayrıldı

1
Temel grafiklerde de saydamlık yapabilirsiniz.
hadley

2
Aynen öyle. Bunu tamamen unutmuştum, bir şeyler yapmanın kafes yoluna alışmıştım. İlgilenenler için renk dizenize birkaç karakter daha eklersiniz, örneğin #FF000080. ?rgbdetayları var.
Aaron Stack Overflow'dan ayrıldı

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.