Индикатор выполнения и отображение (ввод в виде списка)

Я хотел бы следить за ходом моей функции mapply. Данные состоят из 2-х списков и есть функция с 2-мя аргументами.

Если я сделаю что-то подобное с функцией, которая принимает 1 аргумент, я могу использовать ldply вместо lapply. (Я хотел бы rbind.fill вывод в data.frame)

Если я хочу сделать то же самое с mdply, это не сработает, поскольку функция в mdply требует значений, взятых из столбцов фрейма данных или массива. Mapply принимает списки в качестве входных данных.

Эти функции plyr apply удобны не только потому, что я могу получить результат в виде data.frame, но и потому, что могу использовать индикатор выполнения.

Я знаю, что есть пакет pbapply, но нет версии mapply и есть функция txtProgressBar, но я не мог понять, как использовать это с mapply.

Я попытался создать воспроизводимый пример (запуск занимает около 30 секунд)

Думаю, плохой пример. Мой l1 - это список очищенных веб-сайтов (rvest :: read_html), которые я не могу отправить в качестве фрейма данных в mdply. Списки действительно должны быть списками.

mdply <- plyr::mdply

l1 <- as.list(rep("a", 2*10^6+1))
l2 <- as.list(rnorm(-10^6:10^6))

my_func <- function(x, y) {

ab <- paste(x, "b", sep = "_")
ab2 <- paste0(ab, exp(y), sep = "__")

return(ab2)

}

mapply(my_func, x = l1, y = l2)

mdply не работает

mdply(l1, l2, my_func, .progress='text')

Error in do.call(flat, c(args, list(...))) : 'what' must be a function or character string

person Roccer    schedule 14.08.2017    source источник


Ответы (2)


Из ?mdply, осмелюсь сказать, вы не можете указать два ввода данных. Ваше сообщение об ошибке означает, что mdply пытается использовать l2 как функцию, но список не может быть преобразован в функцию ...

Следующее работает нормально

mdply(
    data.frame(x=unlist(l1), y=unlist(l2)), # create a data.frame from l1 and l2
    my_func, # your function
    .progress=plyr::progress_text(style = 3) # create a textual progress bar
)[, 3] # keep the output only

Думаю, теперь я понял вашу цель:

mdply(
    .data=data.frame(r=1:length(l1)), # "fake data" (I will use them as item index)
    .fun=function(r) return(my_func(l1[[r]], l2[[r]])), # a wrapper function of your function
    .progress=plyr::progress_text(style = 3) # create a textual progress bar
)[, 2] # keep the output only

Обратите внимание, мне пришлось заключить вашу функцию в новую, которая учитывает только один аргумент и использует этот аргумент для доступа к l1 и l2

person Bruno Zamengo    schedule 14.08.2017
comment
Спасибо. Проблема в том, что l1 на самом деле представляет собой список веб-страниц, которые я скопировал с помощью rvest :: read_html. Этот список я не могу использовать в качестве столбца в data.frame. Думаю, пример был неудачным. - person Roccer; 14.08.2017
comment
Спасибо за вашу помощь. Функция работает, но результат не тот, что я хочу / получаю от mapply. Я приму ваш ответ позже, когда вы решите на своем примере. - person Roccer; 14.08.2017

Отвечая на свой вопрос. Теперь есть пакет, который может это сделать. Он называется pbapply. Я искал функцию pbmapply.

person Roccer    schedule 17.07.2019