2017-01-02 5 views
1

У меня есть фрейм данных с четырьмя колоннами, и хотите превратить его в кадр данных, с 2 колонками, но вопросы последовательности (так складывают или слияние без дополнительной сортировки не вариант)Более элегантный метод интеркаляции на строки

X1 Y1 X2 Y2 
1 2 3 4 
5 6 7 8 

Для

X1 Y1 
1 2 
3 4 
5 6 
7 8 

Моя некрасиво версия:

nrow = 4 
# Test data set 
d = setNames(data.frame(matrix(sample(1:(nrow*4)), nrow=nrow)), 
      c("X1","Y1","X2","Y2"))d 

# Create empty data frame 
d1 = data.frame(matrix(rep(NA, nrow*2*2), nrow = nrow*2)) 
# Elements 1, 3, 5... 
d1[seq(1, nrow*2, by = 2),] = d[,1:2] 
# Elements 2, 4, 6... 
d1[seq(2, nrow*2, by = 2),] = d[,3:4] 

Не требуется база Р.

Добавлено позже: Я только что нашел:

data.frame(matrix(as.vector(t(as.matrix(d))), nrow = 2*nrow, byrow = TRUE)) 

но выглядит как @akrun имеет несколько более простую версию этого

Альтернативное решение в должности, упомянутой @alistaire, например, с помощью reshape, окончательно не более изящны, чем моя оригинальная версия.

+0

Я не нашел этого, но представленные там решения намного более грязные, чем мой оригинальный. Я пытался избежать ключевого слова «merge» и использовал «intercalate» из моего прошлого исследования ДНК. –

ответ

2

Если столбцы «X» и «Y» чередуются, то перенесем набор данных, преобразовать его в matrix, указав количество столбцов исходного массива данных, разделенных на 2 и преобразовать в data.frame

as.data.frame(matrix(t(df1), ncol= ncol(df1)/2, byrow=TRUE, 
           dimnames = list(NULL, c("X1", "Y1")))) 
# X1 Y1 
#1 1 2 
#2 3 4 
#3 5 6 
#4 7 8 

Или использовать melt из data.table, мы можем взять несколько measurepatterns на основе имени столбца, чтобы преобразовать в формат «длинных»

library(data.table) 
melt(setDT(df1), measure = patterns("^X", "^Y"), 
     value.name = c("X1", "Y1"))[, variable := NULL][order(X1)] 
# X1 Y1 
#1: 1 2 
#2: 3 4 
#3: 5 6 
#4: 7 8