Запускать purrr::map_dfr для строк фрейма данных?

#r #dataframe #functional-programming #purrr #furrr

#r #фрейм данных #функциональное программирование #purrr #furrr

Вопрос:

Учитывая, dataframe скажем iris , значение по умолчанию, как настроить purrr::map_dfr() функцию для запуска в каждой строке dataframe и выполнения функции foo .

Вот одна строка моего df, пожалуйста, примите во внимание, что значение всегда является большим JSON:

 structure(list(Key = "2019/01/04/14/kuku@pupu.com_2ed026cb-8e9f-4392-9cc4-9f580b9d3aab_1345a5a4-3d5b-48a0-a678-67ed09a6f487_2019-01-04-14-52-43-537", 
    LastModified = "2019-01-04T14:52:44.000Z", ETag = ""1c6269ab8b7baa85f0d2567de417f0d0"", 
    Size = 35280, Owner = "e7c0d260939d15d18866126da3376642e2d4497f18ed762b608ed2307778bdf1", 
    StorageClass = "STANDARD", Bucket = "comp-kukupupu-streamed-data", 
    user_name = "kuku@pupu.com", value = list(---here goes a large json), 
    obs_id = 1137L), row.names = 1L, class = "data.frame")
  

и моя функция:

 extract_scroll_data <- function(df) {

  tryCatch({

    j <- fromJSON(unlist(df$value))

    if (is_empty(fromJSON(j$sensorsData)) | is_empty(fromJSON(j$eventList))) {

      return(tibble())

    } else {

      return(set_names(as_tibble(fromJSON(j$eventList, bigint_as_char = TRUE), 
                                 .name_repair = "unique"), 
                       nm = c("time_stamp", 
                              "x", "y", "size", 
                              "pressure", "scroll", "state")) %>%
               dplyr::mutate("user_name" = df$user_name,
                             "obs_id" = df$obs_id))
    }

  }, warning = function(war) {

    # Warning handler picks up where error was generated:
    print(paste0("Warning: occured at ", df$obs_id, war))

  }, error = function(err) {

    # error handler picks up where error was generated
    print(paste0("Error: occured at ", df$obs_id, err))

  }, finally = {

    gc()

  })

}
  

Пожалуйста, сообщите, почему он не использует строки фрейма данных?

Комментарии:

1. просто map_dfr(iris, foo) ? Работает с map_dfr(mtcars, sqrt) но я думаю, вы ищете что-то другое. Можете ли вы подробно объяснить foo ожидаемый результат?

2. Просто не делайте этого.

3. @DavidArenburg спасибо за ваш супер полезный комментарий!

4. @EsbenEickhardt Вскоре я опубликую заголовок фрейма данных и функцию, которую я использую

5. Если ваш фрейм данных слишком огромен для эффективной работы, есть два варианта: 1. Вместо этого работайте с плоским файлом и на время сохраняйте в памяти только немного данных, 2. Используйте пакет SparkR.

Ответ №1:

map_dfr() , поскольку любой другой член map семейства выполняет итерацию по списку, который data.frame на самом деле является списком столбцов. Вы можете проверить это с помощью typeof(iris) и as.list(iris) . Чтобы вместо этого выполнить map_dfr() итерацию по строкам, вам нужно преобразовать свой data.frame в список строк с split() функцией.

 iris %>%
  split(1:nrow(.)) %>%
  purrr::map_dfr(do_stuff)
  

Комментарии:

1. Как насчет использования: furrr::future_pmap_dfr(list(data_df$user_name, data_df$obs_id, data_df$value), function(x, y, z) extract_scroll_data(x, y, z))

2. Это тоже должно сработать

3. Похоже, проблема с extract_scroll_data функцией. Вы уверены, что настроили его так, чтобы он принимал 3 аргумента, а не только data.frame как в вопросе?

4. Конечно, я это сделал. Я думаю, проблема в том, что если я использую pmap со списком из 3 векторов, он использует не 1 элемент из всех 3, затем второй, затем третий, а все комбинации.

5. Ну, так и должно быть. Попробуйте этот код, чтобы изучить его поведение: pmap(list(c('a', 'b', 'c'), c('x', 'y', 'z')), paste)