Мне нравится data.table, он быстрый и интуитивно понятный, что может быть лучше? Увы, вот моя проблема: при обращении к data.table
внутри цикла foreach()
(используя реализацию doMC
) я иногда получаю следующую ошибку: ПРИМЕР В ПРИЛОЖЕНИИ
Error in { :
Internal error: .internal.selfref prot is not itself an extptr
Одна из раздражающих проблем здесь заключается в том, что я не могу заставить его воспроизводиться с какой-либо последовательностью, но это произойдет во время некоторых длительных (несколько часов) задач, поэтому я хочу убедиться, что этого никогда не произойдет, если это возможно.
Поскольку я ссылаюсь на одни и те же data.table
, DT
в каждом цикле, я попытался выполнить следующее в начале каждого цикла:
setattr(DT,".internal.selfref",NULL)
... чтобы удалить недопустимый/поврежденный атрибут самореф. Это работает, и внутренняя ошибка selfref больше не возникает. Однако это обходной путь.
Есть идеи по решению корневой проблемы?
Большое спасибо за любую помощь!
Эрик
Приложение: Сокращенная информация о сеансе R для подтверждения последних версий:
R version 2.15.3 (2013-03-01)
Platform: x86_64-apple-darwin9.8.0/x86_64 (64-bit)
other attached packages:
[1] data.table_1.8.8 doMC_1.3.0
Пример с использованием смоделированных данных. Возможно, вам придется запускать функцию history()
много раз (например, сотни), чтобы получить ошибку:
##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
## Load packages and Prepare Data
##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
require(data.table)
##this is the package we use for multicore
require(doMC)
##register n-2 of your machine's cores
registerDoMC(multicore:::detectCores()-2)
## Build simulated data
value.a <- runif(500,0,1)
value.b <- 1-value.a
value <- c(value.a,value.b)
answer.opt <- c(rep("a",500),rep("b",500))
answer.id <- rep( 6000:6499 , 2)
question.id <- rep( sample(c(1001,1010,1041,1121,1124),500,replace=TRUE) ,2)
date <- rep( (Sys.Date() - sample.int(150, size=500, replace=TRUE)) , 2)
user.id <- rep( sample(250:350, size=500, replace=TRUE) ,2)
condition <- substr(as.character(user.id),1,1)
condition[which(condition=="2")] <- "x"
condition[which(condition=="3")] <- "y"
##Put everything in a data.table
DT.full <- data.table(user.id = user.id,
answer.opt = answer.opt,
question.id = question.id,
date = date,
answer.id = answer.id,
condition = condition,
value = value)
##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
## Daily Aggregation Function
##
##a basic function that aggregates all the values from
##all users for every question on a given day:
##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
each.day <- function(val.date){
DT <- DT.full[ date < val.date ]
#count the number of updates per user (for weighting)
setkey(DT, question.id, user.id)
DT <- DT[ DT[answer.opt=="a",length(value),by="question.id,user.id"] ]
setnames(DT, "V1", "freq")
#retain only the most recent value from each user on each question
setkey(DT, question.id, user.id, answer.id)
DT <- DT[ DT[ ,answer.id == max(answer.id), by="question.id,user.id", ][[3]] ]
#now get a weighted mean (with freq) of the value for each question
records <- lapply(unique(DT$question.id), function(q.id) {
DT <- DT[ question.id == q.id ]
probs <- DT[ ,weighted.mean(value,freq), by="answer.opt" ]
return(data.table(q.id = rep(q.id,nrow(probs)),
ans.opt = probs$answer.opt,
date = rep(val.date,nrow(probs)),
value = probs$V1))
})
return(do.call("rbind",records))
}
##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
## foreach History Function
##
##to aggregate accross many days quickly
##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
history <- function(start, end){
#define a sequence of dates
date.seq <- seq(as.Date(start),as.Date(end),by="day")
#now run a foreach to get the history for each date
hist <- foreach(day = date.seq, .combine = "rbind") %dopar% {
#setattr(DT,".internal.selfref",NULL) #resolves occasional internal selfref error
each.day(val.date = day)
}
}
##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
## Examples
##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
##aggregate only one day
each.day(val.date = "2012-12-13")
##generate a history
hist.example <- history (start = "2012-11-01", end = Sys.Date())
setattr
, а неsetattrib
. Для правильного решения Arun не нуждается в надежной воспроизводимости, но если вы вставите код, мы, вероятно, сможем правильно провести его стресс-тест, чтобы он не работал. - person Matt Dowle   schedule 11.03.2013doMC
был обновлен до 1.3.0 22 февраля, а data.table до 1.8.8 6 марта. Пожалуйста, не забудьте предоставить номера версий всего, что вы используете, например.sessionInfo()
. - person Matt Dowle   schedule 11.03.2013setattrib
- это была моя опечатка в предложении для вас вне списка несколько недель назад! - person Matt Dowle   schedule 11.03.2013doMC
, так что урезанный пример действительно нужен (во всяком случае, мне) для правильного исправления. - person Matt Dowle   schedule 11.03.2013