2016-03-04 5 views
2

Скажем, у меня есть кадр данных. В моем приложении, размеры и имена столбцов этого фрейма данных априори неизвестны, но, к примеру:Объединить результаты применения столбца

v1 <- sample(1:100, 5, replace=F) 
    v2 <- sample(1:100, 5, replace=F) 
    v3 <- sample(1:100, 5, replace=F) 

    sample_matrix <- data.frame(v1, v2, v3) 

Я хочу, чтобы применить функцию для каждой строки sample_df. Функция, по сути, также неизвестна, за исключением того, что она возвращает вектор. В результате операции apply мне нужно иметь фрейм данных с таким же количеством строк.

Если функция возвращает вектор дольше 1, результаты применяются комбинируются в виде столбцов, а не как строки:

dummy_func1 <- function(x) c(1, 2) 
    apply(sample_matrix, 1, dummy_func1) 

    X1 X2 X3 X4 X5 
    1 1 1 1 1 1 
    2 2 2 2 2 2 

Если я знаю заранее, что функция возвращает более 1 аргумент, это может быть рассматриваются транспонированной:

data.frame(t(apply(sample_matrix, 1, dummy_func1))) 

    X1 X2 
    1 1 2 
    2 1 2 
    3 1 2 
    4 1 2 
    5 1 2 

Однако, если функция возвращает ровно 1 аргумент, он делает противоположное от того, что необходимо:

dummy_func2 <- function(x) c(1) 
    data.frame(t(apply(sample_matrix, 1, dummy_func2)) 

    X1 X2 X3 X4 X5 
    1 1 1 1 1 1 

В настоящее время, что я делаю в моем проекте, это транспонировать условно, который является своего рода некрасиво:

res <- data.frame(apply(sample_matrix, 1, dummy_func2)) 
    if(ncol(res) > 1) res <- t(res) 

Ответы Я считаю, в основном предлагают использовать plyr, но я думаю, что я не могу использовать plyr (или я могу?) , потому что в моем проекте ни кадр данных, ни функция не известны заранее.

Мой вопрос в том, что лучший способ вместо использования ванили применять, чтобы результаты всегда объединялись в столбцы, независимо от длины возврата.

ответ

1

вы можете использовать lapply(), так что вы всегда получите список результатов:

sample_matrix<-t(sample_matrix) 

dummy_func1 <- function(x) c(1, 2) 
a <- lapply(as.data.frame(sample_matrix) , dummy_func1) 

t(data.frame(a)) 
     [,1] [,2] 
    v1 1 2 
    v2 1 2 
    v3 1 2 

dummy_func2 <- function(x) c(1) 
b<- lapply(as.data.frame(sample_matrix), dummy_func2) 

t(data.frame(b)) 
     [,1] 
    v1 1 
    v2 1 
    v3 1   
+0

Спасибо большое! Использование lapply - действительно хорошая идея. Меня беспокоит только то, что слишком много транспозиций не будет очень эффективным, если набор данных будет большим. –

+0

Я бы не стал слишком беспокоиться; попробуйте, например, 'big <- data.frame (rnorm (5e6), rnorm (5e6)); system.time (t (большой)) ' –

+1

Говоря о транспозиции, я только заметил, что мой первоначальный ответ не соответствовал вашим спецификациям, потому что вы хотели, чтобы набросок применялся. Соответственно отредактировал мой ответ. –

Смежные вопросы