14 Stimmen

Wie verschiebt man Spalten eines Datenrahmens nach den ersten paar Spalten in Zeilen?

Ich habe einen Datenrahmen, bei dem jede Zeile eine Reihe von Schulen darstellt

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

Ich möchte dies in eine Randliste umwandeln

  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 Paket igraph).

Ich mache es folgendermaßen:

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 hinzufügen möchte (z. B. "Uni"). Wie kann ich dies vektorisiert tun?

11voto

Tyler Rinker Punkte 103407

Hier ist 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])))

6voto

Matthew Lundberg Punkte 41249

Direktes Übersetzen des Codes des Auftraggebers in eine Anwendung. 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
}

))

3voto

Ricardo Saporta Punkte 53183

Nach der Methode von @Tyler arbeiten:

# 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

2voto

thelatemail Punkte 85662

Eine Alternative mit einer Matrixausgabe, wie sie von der 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 in ein Diagramm umwandeln:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X