2014-01-12 5 views
4

У меня есть функция, которую я применяю в списке фреймов данных или матриц (df) с использованием mapply. Функция выводит четыре разных типа кадров данных (например, a: d) на основе некоторых критериев преобразования исходного кадра данных, но у меня возникают проблемы, так как функция позволяет мне выводить только один. Я попытался собрать их в список, но когда я запускаю упрощенную функцию, я получаю это.Возвращение нескольких списков в mapply

df1<-matrix(rnorm(10), nrow=10, ncol=10) 
df2<-df1 
df<-list(df1, df2) 

func<-function (x) { 
    a<-x*1 
    b<-x*2 
    c<-x*3 
    d<-x*4 
    return(list(a,b,c,d)) 
} 

finalresult<-mapply(func, x=df) 

str(finalresult) 

List of 8 
$ : num [1:10, 1:10] -3.211 -0.121 -0.2 0.491 1.118 ... 
$ : num [1:10, 1:10] -6.422 -0.242 -0.4 0.982 2.235 ... 
$ : num [1:10, 1:10] -9.633 -0.362 -0.6 1.473 3.353 ... 
$ : num [1:10, 1:10] -12.844 -0.483 -0.8 1.964 4.471 ... 
$ : num [1:10, 1:10] -3.211 -0.121 -0.2 0.491 1.118 ... 
$ : num [1:10, 1:10] -6.422 -0.242 -0.4 0.982 2.235 ... 
$ : num [1:10, 1:10] -9.633 -0.362 -0.6 1.473 3.353 ... 
$ : num [1:10, 1:10] -12.844 -0.483 -0.8 1.964 4.471 ... 
- attr(*, "dim")= int [1:2] 4 2 

В этом случае вы можете видеть, что это просто дает мне список из четырех кадров выходных данных (A: D) от df1, а затем добавляет следующий набор выходов из df2 сразу после. Я хочу получить вывод, где каждое преобразование фрейма данных помещается в список, где я могу получить к нему доступ по категориям (например, finalresults $ a). Любая помощь будет очень высоко ценится!

Спасибо, -Chelsea

+2

Установите 'УПРОЩЕН = FALSE' в' mapply'. –

+0

Благодарим за отзыв! Я получаю ошибку, когда я запускаю ее с помощью SIMPLIFY = FALSE: SI: Ошибка в функции (x): неиспользуемый аргумент (ы) (SIMPLY = dots [[2]] [[1]]) – Chelsea

+0

вам нужно использовать ' SIMPLIFY = FALSE', а не 'SIMPLY = FALSE' (!) –

ответ

3

Как насчет:

Использование mapply но не упрощать.

result1 <- mapply(func, x=df, SIMPLIFY=FALSE) 

Итерации по индексам (это предполагает, что оба списка в результате имеют одинаковую длину); для каждого индекса i, используйте lapply, чтобы вытащить i-й элемент каждого списка в result1.

result2 <- lapply(seq_along(result1[[1]]), 
       function(i) lapply(result1,"[[",i)) 

Я попытался немного укорачивать/затемнять это еще больше (т.е. удалить необходимость определения анонимной функции), но с вложенными lapply с я не могу вполне понять, как заставить его работать.

+0

Это работает, и он быстро запускается через мой вывод. Спасибо за решение! – Chelsea

+0

, чтобы быть справедливым, я думаю, что ответ Ханс Роггемана в основном такой же, как у меня; мой взгляд выглядит проще, потому что (1) он немного лучше отформатирован; (2) он включил код генерации данных; (3) он добавил некоторые дополнительные функции, чтобы назвать результаты. –

1

Вот решение, которое дает то, что вы хотите. Он в основном называет возвращаемый список, а затем агрегирует его по имени.

df1<-matrix(rnorm(10), nrow=10, ncol=10) 
df2<-df1 
df<-list(df1, df2) 
namesToReferTo = letters[1:4] 
func<-function (x) { 
    a<-x*1; b<-x*2; c<-x*3; d<-x*4 
    retList = list(a,b,c,d) 
    names(retList)=namesToReferTo 
    return(retList) 
} 
finalresult = lapply(namesToReferTo, function(y) { lapply(lapply(df,func), function(x) { x[[y]] }) }) 
# alternatively: finalresult = lapply(namesToReferTo, function(y) { Map(function(x) { return(x[[y]])} , lapply(df,func)) }) 
names(finalresult) = namesToReferTo 
str(finalresult) 
finalresult$b