我有一个数据框架,里面有蜥蜴内脏中各种节肢动物的长度和宽度。因为一些内脏有数千种特定的猎物,所以我只测量了每种猎物类型的一个子集。现在我想用猎物的平均长度和宽度替换每个未测量的个体。我想保留数据帧,只添加指定的列(length2、width2)。主要原因是,每一行也有列,其中包含收集火蜥蜴的日期和位置的数据。我可以用随机选择的被测量个体来填充NA,但为了便于讨论,让我们假设我只想用平均值替换每个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个不同的分类群,总共有大约30,000个猎物项目。这似乎是plyr包可能是理想的,但我只是不知道如何做到这一点。我不是很精通R或编程,但我正在努力学习。
我不知道我在做什么,但如果有帮助的话,我会试着创建一个小的数据集。
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))
})有什么建议吗?
发布于 2012-02-17 12:38:16
这不是我自己的技术,我之前在黑板上看到过:
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)
)发布于 2019-10-28 22:50:54
其他几个选项:
1)采用的全新 nafill**-function**
library(data.table)
setDT(dat)
cols <- c("length", "width")
dat[, (cols) := lapply(.SD, function(x) nafill(x, type = "const", fill = mean(x, na.rm = TRUE)))
, by = taxa
, .SDcols = cols][]带有 's na.aggregate**-function**的2)
library(zoo)
library(data.table)
setDT(dat)
cols <- c("length", "width")
dat[, (cols) := lapply(.SD, na.aggregate)
, by = taxa
, .SDcols = cols][]na.aggregate的默认函数是mean;如果您想使用另一个函数,则应该在FUN-parameter中指定该函数(例如:FUN = median)。另请参阅?na.aggregate的帮助文件。
当然,您也可以在tidyverse中使用以下内容:
library(dplyr)
library(zoo)
dat %>%
group_by(taxa) %>%
mutate_at(cols, na.aggregate)发布于 2015-09-02 22:10:15
在回答这个问题之前,我想说我是R的初学者。因此,如果你觉得我的答案是错的,请告诉我。
代码:
DF[is.na(DF$length), "length"] <- mean(na.omit(telecom_original_1$length))并对宽度应用相同的方法。
DF代表data.frame的名称。
谢谢,帕蒂
https://stackoverflow.com/questions/9322773
复制相似问题