l_ply: как передать атрибут name списка в функцию? - PullRequest
12 голосов
/ 23 августа 2010

Скажем, у меня есть список R, как этот:

> summary(data.list)
                                 Length Class      Mode
aug9104AP                        18     data.frame list
Aug17-10_acon_7pt_dil_series_01  18     data.frame list
Aug17-10_Picro_7pt_dil_series_01 18     data.frame list
Aug17-10_PTZ_7pt_dil_series_01   18     data.frame list
Aug17-10_Verat_7pt_dil_series_01 18     data.frame list

Я хочу обработать каждый data.frame в списке, используя l_ply, но мне также нужно, чтобы имя (например, aug9104AP) было передано в функцию обработки вместе с data.frame. Что-то вроде:

l_ply(data.list,function(df,...) {

    cli.name<- arg_to_access_current_list_item_name

    #make plots with df, use cli.name in plot titles
    #save results in a file called cli.name

  }, arg_to_access_current_list_item_name
)

Что должно быть arg_to_access_current_list_item_name?

Ответы [ 3 ]

11 голосов
/ 25 августа 2010

Проще всего начать с имен, а затем использовать их, чтобы извлечь интересующий вас бит:

l_ply(names(data.list),function(name,...) {
  df <- data.list[[name]]
)

Вы также можете использовать m_ply для передачи как имени, так и данных:

m_ply(cbind(names(data.list), data.list), function(name, df, ...) {
   ...
}
3 голосов
/ 24 августа 2010

Joris ответ - самый чистый способ сделать это. Я бы добавил функцию для извлечения атрибута:

for(ename in names(data.list)) {
    attr(data.list[[ename]], "ename") <- ename
}
ename <- function(x) attr(x, "ename") # states for element name

Таким образом, вы используете его как:

l_ply(data.list, function(df, ...) {
    cli.name<- ename(df)
    # make plots, save results using cli.name
})

Я обычно использую этот метод:

l_ply(names(data.list), function(cli.name, df=data.list[[cli.name]], ...) {
    # make plots, save results using cli.name
})

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


Просто для уведомления есть взлом. Я не рекомендую это, потому что это портит фреймы, и это трудно контролировать.
Используя тот факт, что llply на самом деле является циклом for, вы можете извлечь фактический шаг изнутри функции. Это можно сделать с помощью get в правильной среде.

l_ply(data.list, function(df, ...) {
    cli.name<- names(data.list)[get("i",parent.frame())]
    # make plots, save results using cli.name
})
3 голосов
/ 24 августа 2010

Если вы передаете их один за другим, вы можете использовать deparse (замещать (arg)), например:

test <- function(x){
       y <- deparse(substitute(x))
       print(y)
       print(x)
 }

 var <- c("one","two","three")
 test(var)
[1] "var"
[1] "one"   "two"   "three"

для l_ply, вам придется прибегнуть к добавлению атрибута в списокНапример:

for(i in 1:length(data.list)){
    attr(data.list[[i]],"name") <- names(data.list)[i]
}

Тогда вы можете использовать attr:

cli <- attr(x,"name")

Cheers

...