2012-03-01 10 views
6

Estoy usando dlply() con una función personalizada que promedia inclinaciones de lm() se ajusta a datos que contienen algunos valores NA, y me sale el error "error en lm.fit (x, y, compensado = offset, singular.ok = singular.ok, ...): 0 casos (no-NA)"lm llamado desde dentro arroja el error "0 (no NA) casos" [r]

Este error sólo ocurre cuando llamo dlply con dos variables clave, la separación por una variable funciona bien.

Annoyingly no puedo reproducir el error con un conjunto de datos simple, así que he publicado el conjunto de datos del problema en mi dropbox.

Aquí está el código, ya que reduce al mínimo posible sin dejar de producir un error:

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 

Gracias de antemano por cualquier idea.

+1

Yo diría que el error es informativo. Si miras los valores en cada subconjunto de tus datos, supongo que encontrarás un subconjunto de todos los 'NA'. Intente reemplazar su llamada de lm en su función con algo que pueda identificar 'all (is.na())'. – Justin

Respuesta

5

Para varios de sus clasificaciones cruzadas tiene covariables que faltan:

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 

Esto le permitiría pasar por alto los subconjuntos con insuficiente datos en esta información en particular:

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)) } 
} 

Aunque depende de la falta de una covariable en particular. Una solución más robusta sería usar try para capturar errores y convertir a NA.

?try 
+0

Oh, ya veo, no lo conseguí que lm() estaba lanzando errores en lugar de NA. Es un consejo útil. –

+0

La forma de ver qué es lo que está arrojando el error es ejecutar 'traceback()'. –

2

Según mi comentario:

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

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

muestra que tiene muchos conjuntos sub donde F1 y el1 son NA. (De hecho, cada vez que uno es todo na, el otro es así!)

+0

Gracias a ti y @DWin por ese punto - lo que no entiendo es, ¿cómo puedo obtener dlply() para poner pendientes en los elementos de la lista cuando están disponibles, y NA (o similar) cuando están ¿no? Pensé que funciona correctamente en subconjuntos de marcos de datos de forma más o menos independiente, de modo que una NA en un subconjunto no interfiera con los otros subconjuntos, pero supongo que ese no es el caso. –

+0

Más claro: una forma de manejar las NA sería atraparlos en la función meanSlope, pero creo que debería haber una mejor manera ... –

+0

'dlply' no es la culpa aquí. está manejando cada subconjunto independientemente como esperabas. sin embargo, si alimenta un subconjunto a 'lm' que es todo NA, se producirá un error. trataste de manejar el caso donde algunos valores eran NA correctamente, pero no puedes alimentar 'lm' a un subconjunto vacío, que es lo que tienes si' na.omit' es un subconjunto con todos los NA. en su lugar, agregue una línea como 'if (all (is.na (df)) return (NA)' antes de la llamada 'lm'. – Justin

Cuestiones relacionadas