Почему sapply возвращает матрицу, которую мне нужно транспонировать, а затем транспонированная матрица не будет присоединяться к фрейму данных?

буду признателен за понимание, почему это происходит и как я могу сделать это более красноречиво.

когда я использую sapply, я хотел бы вернуть матрицу 3x2, но она возвращает матрицу 2x3. Почему так? И почему это трудно прикрепить к другому фрейму данных?

a <- data.frame(id=c('a','b','c'), var1 = c(1,2,3), var2 = c(3,2,1))
out <- sapply(a$id, function(x) out = a[x, c('var1', 'var2')])
#out is 3x2, but I would like it to be 2x3
#I then want to append t(out) (out as a 2x3 matrix) to b, a 1x3 dataframe
b <- data.frame(var3=c(0,0,0))

когда я пытаюсь прикрепить эти,

b[,c('col2','col3')] <- t(out)

ошибка, которую я получаю:

Warning message:
In `[<-.data.frame`(`*tmp*`, , c("col2", "col3"), value = list(1,  :
  provided 6 variables to replace 2 variables

хотя следующее, кажется, дает желаемое результат:

rownames(out) <- c('col1', 'col2')
b <- cbind(b, t(out))

Я не могу работать с переменными:

b$var1/b$var2

возвращает

Error in b$var1/b$var2 : non-numeric argument to binary operator

спасибо!

3 ответов


чтобы расширить ответ DWin: это поможет взглянуть на структуру вашего


сначала немного R обозначения. Если вы посмотрите на код sapply, вы найдете ответ на свой вопрос. The sapply функция проверяет, равны ли длины списка, и если да, то сначала "unlist()"s их, а затем принимает эту серию списков в качестве аргумента данных в array(). С array (например, matrix ()) по умолчанию упорядочивает свои значения в основном порядке столбцов, вот что вы получаете. Списки переворачиваются на их сторону. Если вам это не нравится, вы можете определить новый функция tsapply это вернет транспонированные значения:

> tsapply <- function(...) t(sapply(...))
> out <- tsapply(a$id, function(x) out = a[x, c('var1', 'var2')])
> out
     var1 var2
[1,] 1    3   
[2,] 2    2   
[3,] 3    1 

... матрица 3 х 2.


посмотрите на ddply из пакета plyr

a <- data.frame(id=c('a','b','c'), var1 = c(1,2,3), var2 = c(3,2,1))

library(plyr)
ddply(a, "id", function(x){
    out <- cbind(O1 = rnorm(nrow(x), x$var1), O2 = runif(nrow(x)))
    out
})