Amo data.table, è veloce e intuitivo, cosa potrebbe essere migliore? Ahimè, ecco il mio problema: quando si parla di un data.table
all'interno di un ciclo foreach()
(usando l'implementazione doMC
) io a volte il seguente errore: ESEMPIO IN APPENDICEOttenere un errore selfref interno casuale in data.table per R
Error in { :
Internal error: .internal.selfref prot is not itself an extptr
Uno dei fastidiosi problemi qui è che non riesco a riprodurlo con una certa coerenza, ma accadrà durante alcune lunghe (molte ore) attività, quindi voglio assicurarmi che non accada mai, se possibile.
Dal momento che si riferiscono allo stesso data.table
, DT
, in ogni ciclo, ho provato a fare funzionare il seguente all'inizio di ogni ciclo:
setattr(DT,".internal.selfref",NULL)
... per rimuovere l'attributo non valido/corrotto auto rif. Funziona e l'errore selfref interno non si verifica più. È una soluzione, però.
Qualche idea per affrontare il problema di root?
Molte grazie per qualsiasi aiuto!
Eric
Appendice: R abbreviate Info Sessione per confermare le versioni più recenti:
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
esempio utilizzando dati simulati - potrebbe essere necessario eseguire i history()
funzione molte volte (come, centinaia) per ottenere l'errore:
##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
## 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())
puoi incollare qui l'implementazione del ciclo foreach (anche se potrebbe non riprodurre il problema come dici tu?)? – Arun
Re il tentativo di soluzione, buona idea, ma è 'setattr' non' setattrib'. Per la soluzione corretta Arun è azzeccata, non ha bisogno di essere riproducibile in modo affidabile, ma se si incolla il codice possiamo probabilmente stressarlo nel modo giusto per farlo fallire. –
E vedo 'doMC' è stato aggiornato a 1.3.0 il 22 febbraio e data.table a 1.8.8 il 6 marzo. Assicurati di fornire i numeri di versione di tutto ciò che stai utilizzando in anticipo, ad es. 'SessionInfo()'. –