2013-02-12 9 views
14

I haben, wobei jede Zeile einen Datenrahmen eine Folge von SchulenWie verschiebt man Spalten eines Datenrahmens in Zeilen nach den ersten Spalten?

repräsentiere
edu <- read.table(header=TRUE, text="Elem Mid High 
e1 m1 h1 
e2 m2 h2 
e1 m2 h2 
e3 m1 h1") 

Ich möchte das in eine Kantenliste zu transformieren

s1 s2 
1 e1 m1 
2 e2 m2 
3 e1 m2 
4 e3 m1 
5 m1 h1 
6 m2 h2 
7 m2 h2 
8 m1 h1 

für einen gerichteten Graphen (über das IGRAPH Paket) .

Hier ist, wie ich es tun:

e2m <- edu[,1:2] 
m2h <- edu[,2:3] 
colnames(e2m) <- c("s1", "s2") 
colnames(m2h) <- c("s1", "s2") 
schools <- rbind(e2m,m2e) 

„Schulen“ enthält, was ich will, aber es ist iterativ und wird umständlich, wenn ich eine vierte Spalte (zum Beispiel „Uni“) hinzufügen möchten. Was ist der vektorisierte Weg, dies zu tun?

+9

Kann ich sagen, dass dies, dass Sie (1) 'fragte um eine Frage, (2)' bieten eine kleine Arbeitsdaten Set', (3) eine große Frage ist 'zeige gewünschte Ausgabe' und (4)' was du gerade tust.' +1 –

+0

Ich bin leider unerfahren in seiner Verwendung, aber ist das nicht was 'schmelzen' -' recast' tut? –

+0

@Carl, dachte ich genauso, aber das ist nicht der Fall, zumindest nicht einfach. Beachten Sie, dass die erste Spalte des transformierten 'dat.frame' sowohl die erste Spalte als auch die zweite Spalte von' edu' enthält. – Arun

Antwort

11

ist hier eine mögliche Lösung:

len <- seq_along(edu) 
a <- head(len, -1) 
b <- tail(len, -1) 

data.frame(s1=as.character(unlist(edu[, a])), s2=as.character(unlist(edu[, b]))) 
+0

Die ersten beiden sind nicht ganz richtig (zu viele Kombinationen werden gedruckt). "Edit2" ist korrekt und großartig. –

+0

+1 für die letzte! – agstudy

+0

+1 Brillant! . –

6

direkt auf den OP des Code in eine Anwendung zu übersetzen. Dies ist nicht vektorisiert:

do.call(rbind, lapply(seq(ncol(edu)-1), FUN=function(x){ 
    r <- edu[,x:(x+1)] 
    colnames(r) <- c('s1', 's2') 
    r 
} 

)) 
2

Eine Alternative mit einem Matrix-Ausgang, erforderlich durch die igraph Funktionen.

t(
    matrix(
    apply(edu,1,function(x) x[c(1,rep(2:(length(x)-1),each=2),length(x))]), 
    nrow=2 
     ) 
) 

Ergebnis:

 [,1] [,2] 
[1,] "e1" "m1" 
[2,] "m1" "h1" 
[3,] "e2" "m2" 
[4,] "m2" "h2" 
[5,] "e1" "m2" 
[6,] "m2" "h2" 
[7,] "e3" "m1" 
[8,] "m1" "h1" 

und Konvertieren in einem Diagramm:

> graph.edgelist(result) 
IGRAPH DN-- 7 8 -- 
+ attr: name (v/c) 
3

weg von Arbeiten bei Tylers Methode:

# assuming a new column added 
edu$Uni <- as.factor(c("u1", "u2", "u1", "u1")) 

.

rows <- nrow(edu) 
total <- prod(dim(edu)) # ie: nrow(edu) * ncol(edu) 

X <- as.character(unlist(edu)) 
data.frame(s1=X[1:(total-rows)], s2=X[(rows+1):total]) 

Ergebnisse:

s1 s2 
1 e1 m1 
2 e2 m2 
3 e1 m2 
4 e3 m1 
5 m1 h1 
6 m2 h2 
7 m2 h2 
8 m1 h1 
9 h1 u1 <~~~ Added "Uni" column 
10 h2 u2 <~~~ Added "Uni" column 
11 h2 u1 <~~~ Added "Uni" column 
12 h1 u1 <~~~ Added "Uni" column 
+0

Meine ersten Versuche ergaben 12 Zeilen, das ist zu viel. –

+0

Hinweis Ich habe eine Spalte hinzugefügt, daher 12 statt 8 –

+0

Oh, hab es :) +1 –

Verwandte Themen