Come sostituire NA con media per sottoinsieme in R (imputare con plyr?)

Ho un dataframe con le lunghezze e le larghezze di vari artropodi dalle viscere delle salamandre. Poiché alcune viscere avevano migliaia di determinati oggetti di preda, ho misurato solo un sottoinsieme di ciascun tipo di preda. Ora voglio sostituire ogni individuo non misurato con la lunghezza media e la larghezza per quella preda. Voglio mantenere il dataframe e aggiungere solo colonne calcolate (length2, width2). Il motivo principale è che ogni riga contiene anche colonne con dati relativi alla data e alla posizione in cui è stata raccolta la salamandra. Potrei riempire il NA con una selezione casuale degli individui misurati, ma per ragioni ipotizziamo di voler sostituire ogni NA con la media.

Ad esempio, immagina di avere un dataframe che assomigli a qualcosa:

id taxa length width 101 collembola 2.1 0.9 102 mite 0.9 0.7 103 mite 1.1 0.8 104 collembola NA NA 105 collembola 1.5 0.5 106 mite NA NA 

In realtà ho più colonne e circa 25 taxa diversi e un totale di ~ 30.000 elementi di prede in totale. Sembra che il pacchetto plyr potrebbe essere l’ideale per questo, ma non riesco a capire come farlo. Non sono molto esperto di programmazione, ma sto cercando di imparare.

Non che io sappia quello che sto facendo, ma cercherò di creare un piccolo set di dati con cui giocare se ti aiuta.

 exampleDF <- data.frame(id = seq(1:100), taxa = c(rep("collembola", 50), rep("mite", 25), rep("ant", 25)), length = c(rnorm(40, 1, 0.5), rep("NA", 10), rnorm(20, 0.8, 0.1), rep("NA", 5), rnorm(20, 2.5, 0.5), rep("NA", 5)), width = c(rnorm(40, 0.5, 0.25), rep("NA", 10), rnorm(20, 0.3, 0.01), rep("NA", 5), rnorm(20, 1, 0.1), rep("NA", 5))) 

Ecco alcune cose che ho provato (che non hanno funzionato):

 # mean imputation to recode NA in length and width with means (could do random imputation but unnecessary here) mean.imp <- function(x) { missing <- is.na(x) n.missing <-sum(missing) x.obs <-a[!missing] imputed <- x imputed[missing] <- mean(x.obs) return (imputed) } mean.imp(exampleDF[exampleDF$taxa == "collembola", "length"]) n.taxa <- length(unique(exampleDF$taxa)) for(i in 1:n.taxa) { mean.imp(exampleDF[exampleDF$taxa == unique(exampleDF$taxa[i]), "length"]) } # no way to get back into dataframe in proper places, try plyr? 

un altro tentativo:

 imp.mean <- function(x) { a <- mean(x, na.rm = TRUE) return (ifelse (is.na(x) == TRUE , a, x)) } # tried but not sure how to use this in ddply Diet2 <- ddply(exampleDF, .(taxa), transform, length2 = function(x) { a <- mean(exampleDF$length, na.rm = TRUE) return (ifelse (is.na(exampleDF$length) == TRUE , a, exampleDF$length)) }) 

Qualche suggerimento usando plyr o no?