Лучший способ превратить две колонки в одну в R / Splus? - PullRequest
2 голосов
/ 31 марта 2011

В настоящее время я делаю следующее:

x <- cbind(c(1, 2, 3), c(4, 5, 6))
x.merged <- matrix(t(x), ncol=1)

, чтобы создать один столбец со значениями 1, 4, 2, 5, 3, 6, из матрицы x.Но полагаться на t(x) кажется немного неуклюжим.Есть лучший способ сделать это?Я бы хотел избежать цикла for или apply, если есть более простая встроенная функция, которая обрабатывает подобные вещи.

РЕДАКТИРОВАТЬ: Чтобы быть более ясным, x только что дано мне.Первая строка кода выше предназначена только для иллюстрации задействованных значений.Для меня было бы лучше написать:

> x
     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6

Ответы [ 5 ]

7 голосов
/ 31 марта 2011

На самом деле, если вы сделаете его вектором, это займет не более:

> c(t(x))
[1] 1 4 2 5 3 6

Или, если вам действительно нужно избегать t(), вы можете сделать:

> c(apply(x,2,rbind))
[1] 1 4 2 5 3 6

Это работает для произвольного числа столбцов, но включает в себя применение.Если вы не хотите использовать его, вам придется вручную указать все столбцы, которые вы хотите вставить позади друг друга.Но решение t () является самым быстрым:

> n <- 10000000    
> x <- matrix(rnorm(n),ncol=2)
> system.time(c(t(x)))
   user  system elapsed 
   0.07    0.00    0.06 

> system.time(c(rbind(x[,1],x[,2])))
   user  system elapsed 
   0.22    0.05    0.26 

Помните, что матрица может рассматриваться как вектор с добавленными к нему измерениями и всегда читается по столбцам.Таким образом, вы действительно не можете избежать t() в вашем решении.Вы всегда можете использовать его как вектор, например:

> x[4]
[1] 4

просто работает, если вы помните, что матрица читается по столбцам.Так что в вашем случае вам понадобится

> t(x)[4]
[1] 5

Если вам действительно нужно это как матрица, тогда:

> matrix(t(x))
     [,1]
[1,]    1
[2,]    4
[3,]    2
[4,]    5
[5,]    3
[6,]    6
4 голосов
/ 31 марта 2011

Я думаю, что способ сделать это с наименьшим количеством нажатий клавиш:

c(rbind(c(1, 2, 3), c(4, 5, 6)))

Использование rbind исключает транспонирование, а c - самый короткий способ убрать атрибуты (включая измерения) с объекта, хотя использовать его таким способом - немного злоупотребление.

2 голосов
/ 31 марта 2011

РЕДАКТИРОВАТЬ 2

Одним из необязательных аргументов в matrix является заполнение строкой. Мы можем использовать это здесь и очень похоже на ваше оригинальное решение. Очевидно, что вы можете поменять ncol на nrow, если вам это больше подходит.

matrix(x, ncol = 1, byrow = TRUE)
     [,1]
[1,]    1
[2,]    2
[3,]    3
[4,]    4
[5,]    5
[6,]    6

Клянусь, был вопрос по этому поводу, как и вчера, но мне не удалось его найти. Посмотрим, смогу ли я вспомнить некоторые ответы на этот вопрос:

#do.call will execute a function, "c" for combine in this case, over a list so we coerce the 
#matrix to a list
do.call("c", as.list(x))
[1] 1 2 3 4 5 6


#Similar concept with stack, but it expects a data.frame 
stack(as.data.frame(x))
  values ind
1      1  V1
2      2  V1
3      3  V1
4      4  V2
5      5  V2
6      6  V2

#The melt function in package reshape can do this and a lot more when combined with "cast"
library(reshape)
melt(x)
  X1 X2 value
1  1  1     1
2  2  1     2
3  3  1     3
4  1  2     4
5  2  2     5
6  3  2     6

РЕДАКТИРОВАТЬ : Похоже, я должен был найти вопрос, видя, как я дал ответ, но я отвлекся: R - как добавить регистры одной переменной в другую переменную (стек переменные)

1 голос
/ 31 марта 2011
as.vector(matrix(c(1:3,4:6),byrow=T,nrow=2))
[1] 1 4 2 5 3 6
0 голосов
/ 31 марта 2011

Если у вас есть матрица, а не фрейм данных, нет причин не использовать t.Обратите внимание, что stack использует as.list и lapply, поэтому, вероятно, менее элегантно в этом случае.Однако, если вы хотите просто вектор, вы можете опустить бит matrix(*, ncol=1);просто используйте as.vector.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...