Как перенести столбцы кадра данных в строки после первых нескольких столбцов? - программирование
Подтвердить что ты не робот

Как перенести столбцы кадра данных в строки после первых нескольких столбцов?

У меня есть кадр данных с каждой строкой, представляющей последовательность школ

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

Я хотел бы преобразовать это в список ребер

  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

для ориентированного графа (через пакет igraph).

Вот как я это делаю:

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

"школы" содержат то, что я хочу, но оно итеративно и становится громоздким, если я хочу добавить четвертый столбец (например, "Uni" ). Что такое векторный способ сделать это?

4b9b3361

Ответ 1

Вот возможное решение:

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

Ответ 2

Прямой перевод кода OP в приложение. Это не векторизация:

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

))

Ответ 3

Отключение метода @Tyler:

# 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])

Результаты:

   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

Ответ 4

Альтернатива с выходом матрицы, требуемая функциями igraph.

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

Результат:

     [,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"

И преобразуется в график:

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