Как применить функцию к вложенному списку? - PullRequest
6 голосов
/ 07 сентября 2011

Мне нужно получить максимум переменной во вложенном списке. Для определенного номера станции "s" и определенного участника "m" mylist[[s]][[m]] имеют вид:

station date.time        member  bias
6019    2011-08-06 12:00 mbr003  86
6019    2011-08-06 13:00 mbr003  34

Для каждой станции мне нужно получить максимум bias всех участников. За s = 3 мне удалось сделать это через:

library(plyr)
var1 <- mylist[[3]]
var2 <- lapply(var1, `[`, 4)
var3 <- laply(var2, .fun = max)
max.value <- max(var3)

Есть ли способ избежать номера столбца "4" во второй строке и использовать имя переменной $bias в lapply или лучший способ сделать это?

Ответы [ 3 ]

6 голосов
/ 07 сентября 2011

Вы можете использовать [ с именами столбцов фреймов данных и их индексами. Таким образом, foo[4] будет иметь тот же результат, что и foo["bias"] (при условии, что bias - это имя четвертого столбца).

$bias на самом деле не имя этого столбца. $ - это просто еще одна функция в R, такая как [, которая используется для доступа к столбцам фреймов данных (среди прочего).

Но теперь я собираюсь выйти на передний план и дать несколько советов о вашей структуре данных. Если каждый элемент вашего вложенного списка содержит данные для уникальной комбинации station и member, вот упрощенная игрушечная версия ваших данных:

dat <- expand.grid(station = rep(1:3,each = 2),member = rep(1:3,each = 2))
dat$bias <- sample(50:100,36,replace = TRUE)

tmp <- split(dat,dat$station)
tmp <- lapply(tmp,function(x){split(x,x$member)})

> tmp
$`1`
$`1`$`1`
  station member bias
1       1      1   87
2       1      1   82
7       1      1   51
8       1      1   60

$`1`$`2`
   station member bias
13       1      2   64
14       1      2  100
19       1      2   68
20       1      2   74
etc.

tmp - это список длины три, где каждый элемент сам является списком длины три. Каждый элемент представляет собой фрейм данных, как показано выше.

Действительно гораздо проще записать данные такого типа в виде одного фрейма данных. Вы заметите, что я построил его таким образом (dat), а затем разделил его дважды. В этом случае вы можете rbind все это снова, используя код, подобный следующему:

newDat <- do.call(rbind,lapply(tmp,function(x){do.call(rbind,x)}))
rownames(newDat) <- NULL

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

library(plyr)
#Find the max bias for each unique station+member
ddply(newDat,.(station,member),summarise, mx = max(bias))
  station member  mx
1       1      1  87
2       1      2 100
3       1      3  91
4       2      1  94
5       2      2  88
6       2      3  89
7       3      1  74
8       3      2  88
9       3      3  99

#Or maybe the max bias for each station across all members
ddply(newDat,.(station),summarise, mx = max(bias))
  station  mx
1       1 100
2       2  94
3       3  99
1 голос
/ 07 сентября 2011

Вот еще одно решение с использованием повторяющихся lapply.

lapply(tmp, function(x) lapply(lapply(x, '[[', 'bias'), max))
1 голос
/ 07 сентября 2011

Возможно, вам придется использовать [[ вместо [, но он должен хорошо работать со строкой (не используйте $).попробуйте:

var2 <- lapply( var1, [, 'bias' )

или

var2 <- lapply( var1, [[, 'bias' )

в зависимости от того, является ли var1 списком.

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