Проблема совместимости структуры данных между параллелизацией foreach и tibble - PullRequest
1 голос
/ 07 февраля 2020

Я обнаружил, что функция pec::predictSurvProb отлично работает в foreach l oop при использовании объектов класса data.frame, но не при использовании объектов класса tbl_df, который представляется по умолчанию tibble класс производится при использовании dplyr манипуляции. Я получаю сообщение об ошибке, которое не сильно помогло: Ошибка в {: задача 1 не выполнена - "Не совместим с запрошенным типом: [type = list; target = double]."

Решением было преобразовать мои данные в класс data.frame из tbl_df, но мне любопытно, почему возникает эта проблема. Похоже, что тиблы на самом деле не являются расширениями фреймов данных, потому что они ведут себя по-разному, и это поведение несовместимо с другими пакетами R.

Я не уверен, что этот тип несовместимости хорошо документирован, но я нашел краткое обсуждение здесь: https://stat.ethz.ch/pipermail/r-package-devel/2017q3/001896.html

Я попытался показать проблему в следующий repex:

# repex
library(survival)
library(pec)
library(dplyr)
library(doParallel) 

data("lung") # example data set
class(lung) # which is class data.frame

lung2 <- lung %>%
group_by(inst) %>%
mutate(T_MAX = max(time)) %>%
ungroup() # use dplyr to create a new variable T_MAX

class(lung2) # lung2 is of class tibble (tbl_df)

lung3 <- lung %>%
group_by(inst) %>%
mutate(T_MAX = max(time)) %>%
ungroup() %>%
as.data.frame() # same dplyr manipulation but coercion to class data.frame at the end

class(lung3) # lung3 is of class data.frame

# create identical Cox PH models using the different data sets lung2 and lung3
mdl_lung2 <- coxph(Surv(time, status) ~ inst + age + sex,
               data = lung2,
               x = TRUE)

summary(mdl_lung2)

mdl_lung3 <- coxph(Surv(time, status) ~ inst + age + sex,
               data = lung3,
               x = TRUE)

summary(mdl_lung3)

# predictSurvProb function works and output is the same
predictSurvProb(mdl_lung2, newdata = lung2, times = 365)
predictSurvProb(mdl_lung3, newdata = lung3, times = 365)

# initiate parallelisation
cores <- detectCores() 
registerDoParallel(cores = cores) 
cat("No. of cores initiated for parallel processing:", getDoParWorkers()) 

# foreach application does not work using lung2
lung2$P_TEST <- foreach(j=1:nrow(lung2),
                      .combine = c) %dopar% { # Return a vector
                        predictSurvProb(mdl_lung2, lung2[j, ], times = lung2[j, "T_MAX"])
                      }

# but does using lung3
lung3$P_TEST <- foreach(j=1:nrow(lung3),
                   .combine = c) %dopar% { # Return a vector
                     predictSurvProb(mdl_lung3, lung3[j, ], times = lung3[j, "T_MAX"])
                   }

summary(lung3$P_TEST)
...