2012-03-01 11 views
6

Sto usando dlply() con una funzione personalizzata che ha una pendenza media di lm() che si adatta ai dati che contengono alcuni valori NA e ottengo l'errore "errore nella lm.fit (x, y, offset = compensati, singular.ok = singular.ok, ...): 0 casi (non-NA)"lm chiamato dall'interno dlply genera "0 (non-NA) casi" errore [r]

Questo errore si verifica solo quando chiamo dlply con due variabili chiave - la separazione di una variabile funziona bene.

Annoyingly Non riesco a riprodurre l'errore con un set di dati semplice, quindi ho pubblicato il set di dati problema nella mia casella personale.

Ecco il codice, come ridotto al minimo possibile, pur producendo un errore:

masterData <- read.csv("http://dl.dropbox.com/u/48901983/SOquestionData.csv", na.strings="#N/A") 

workingData <- data.frame(sample = masterData$sample, 
         substrate = masterData$substrate, 
         el1 = masterData$elapsedHr1, 
         F1 = masterData$r1 - masterData$rK) 

#This function is trivial as written; in reality it takes the average of many slopes 
meanSlope <- function(df) { 
    lm1 <- lm(df$F1 ~ df$el1, na.action=na.omit) #changing to na.exclude doesn't help 
    slope1 <- lm1$coefficients[2] 
    meanSlope <- mean(c(slope1)) 
} 

lsGOOD <- dlply(workingData, .(sample), meanSlope) #works fine 

lsBAD <- dlply(workingData, .(sample, substrate), meanSlope) #throws error 

Grazie in anticipo per qualsiasi comprensione.

+1

Direi che l'errore è informativo. Se guardi i valori in ogni sottoinsieme dei tuoi dati, presumo che troverai un sottoinsieme di tutti i 'NA'. Prova a sostituire il tuo lm call nella tua funzione con qualcosa che possa identificare 'all (is.na())'. – Justin

risposta

5

Per molti dei vostri incrociati classificazioni avete covariate mancanti:

with(masterData, table(sample, substrate, r1mis = is.na(r1))) 
# 
snipped the nonmissing reports 
, , r1mis = TRUE 

     substrate 
sample 1 2 3 4 5 6 7 8 
    3 0 0 0 0 0 0 0 0 
    4 0 0 0 0 0 0 0 0 
    5 0 0 0 0 0 0 0 0 
    6 0 0 0 0 0 0 0 0 
    7 0 0 0 0 0 0 3 3 
    8 0 0 0 0 0 0 0 3 
    9 0 0 0 0 0 0 0 3 
    10 0 0 0 0 0 0 0 3 
    11 0 0 0 0 0 0 0 3 
    12 0 0 0 0 0 0 0 3 
    13 0 0 0 0 0 0 0 3 
    14 0 0 0 0 0 0 0 3 

Ciò permetterà di saltare i sottoinsiemi con insufficiente dati in questi particolari dati:

meanSlope <- function(df) { if (sum(!is.na(df$el1)) < 2) { return(NA) } else { 
    lm1 <- lm(df$F1 ~ df$el1, na.action=na.omit) #changing to na.exclude doesn't help 
    slope1 <- lm1$coefficients[2] 
    meanSlope <- mean(c(slope1)) } 
} 

Sebbene dipenda dall'assenza di una particolare covariata. Una soluzione più robusta sarebbe utilizzare try per acquisire errori e convertirli in NA.

?try 
+0

Oh, capisco - non ho capito che lm() stava emettendo errori invece di NA. Questo è un consiglio utile –

+0

Il modo per vedere che cosa sta generando l'errore è eseguire 'traceback()'. –

2

Come per il mio commento:

my.func <- function(df) { 
    data.frame(el1=all(is.na(df$el1)), F1=all(is.na(df$F1))) 
} 

ddply(workingData, .(sample, substrate), my.func) 

dimostra che hai molti set sub dove entrambi F1 e EL1 sono NA. (In realtà ogni volta che uno è tutto na, l'altro è pure!)

+0

Grazie a te e @DWin per quel punto - la cosa che non capisco è, come posso ottenere dlply() per mettere le pendenze negli elementi della lista quando sono disponibili, e NA (o simili) quando sono non? Ho pensato che dlply lavori su sottogruppi di dati frame più o meno indipendentemente così che un NA in un sottoinsieme non interferisca con gli altri sottoinsiemi, ma immagino che non sia il caso. –

+0

Più chiaramente - un modo per gestire gli AN potrebbe essere quello di intrappolarli nella funzione meanSlope, ma sento che dovrebbe esserci un modo migliore ... –

+0

'dlply' non è colpa qui. sta gestendo ogni sottoinsieme in modo indipendente come previsto. tuttavia, se si alimenta un sottoinsieme a 'lm' che è tutto NA, si verificherà un errore. hai provato a gestire il caso in cui alcuni valori erano NA correttamente, ma non puoi nutrire 'lm' un sottoinsieme vuoto, che è ciò che hai se tu' na.omit' un sottoinsieme con tutto il NA. invece, aggiungi una riga come 'if (tutto (is.na (df)) return (NA)' prima della chiamata 'lm. – Justin

Problemi correlati