如何用R中的子集中的均值代替NA(用plyr?进行估计)
我有一个从蝾螈胆量来的各种节肢动物的长度和宽度的数据框。 因为有些胆量有成千上万的猎物,我只测量了每种猎物types的一个子集。 我现在想用每个不可测量的个体来replace那个猎物的平均长度和宽度。 我想保持数据框,只是添加估算列(length2,width2)。 主要原因是每一行也有蝾螈收集date和地点的数据栏。 我可以用随机select的测量个体来填写NA,但是为了论证,我们假设我只想用平均值replace每个NA。
例如,假设我有一个像这样的数据框:
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
事实上,我有更多的专栏和大约25种不同的分类群,总共有大约3万个猎物。 似乎plyr包可能是理想的,但我只是不知道如何做到这一点。 我不是很R或编程精明,但我试图学习。
不是说我知道自己在做什么,但是如果有帮助,我会尝试创build一个小数据集。
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)))
以下是我试过的一些事情(没有奏效):
# 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?
另一个尝试:
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)) })
任何build议使用plyr或不?
不是我自己的技术,我在板子上看到它:
dat <- read.table(text = "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", header=TRUE) library(plyr) impute.mean <- function(x) replace(x, is.na(x), mean(x, na.rm = TRUE)) dat2 <- ddply(dat, ~ taxa, transform, length = impute.mean(length), width = impute.mean(width)) dat2[order(dat2$id), ] #plyr orders by group so we have to reorder
用for
循环编辑非plyr方法:
for (i in which(sapply(dat, is.numeric))) { for (j in which(is.na(dat[, i]))) { dat[j, i] <- mean(dat[dat[, "taxa"] == dat[j, "taxa"], i], na.rm = TRUE) } }
稍后编辑许多卫星,这里是一个data.table & dplyr方法:
data.table
library(data.table) setDT(dat) dat[, length := impute.mean(length), by = taxa][, width := impute.mean(width), by = taxa]
dplyr
library(dplyr) dat %>% group_by(taxa) %>% mutate( length = impute.mean(length), width = impute.mean(width) )
在回答这个问题之前,我想说R是一个初学者。因此,请让我知道如果你觉得我的答案是错误的。
码:
DF[is.na(DF$length), "length"] <- mean(na.omit(telecom_original_1$length))
并应用相同的宽度。
DF代表data.frame的名称。
谢谢,Parthi
在@Tyler Rinker的解决scheme上进行扩展,假设要素是要进行归纳的列。 在这种情况下, features <- c('length', 'width')
。 然后使用data.table
解决scheme变成:
library(data.table) setDT(dat) dat[, (features) := lapply(.SD, impute.mean), by = taxa, .SDcols = features]