2013-11-28 66 views
1

我有一个数据帧,看起来像这样:功能,以填补缺失值

set.seed(300) 
df <- data.frame(site = sort(rep(paste0("site", 1:5), 5)), 
       value = sample(c(1:5, NA), replace = T, 25)) 

df 

    site value 
1 site1 NA 
2 site1  5 
3 site1  5 
4 site1  5 
5 site1  5 
6 site2  1 
7 site2  5 
8 site2  3 
9 site2  3 
10 site2 NA 
11 site3 NA 
12 site3  2 
13 site3  5 
14 site3  4 
15 site3  4 
16 site4 NA 
17 site4 NA 
18 site4  4 
19 site4  4 
20 site4  4 
21 site5 NA 
22 site5  3 
23 site5  3 
24 site5  1 
25 site5  1  

正如你所看到的,有在value列几个遗漏值。我需要将value列中的缺失值替换为网站的平均值。因此,如果在site1处测得的value有缺失值,则需要将site1的平均值value归算。但是,数据帧会不断添加到R中并导入到R中,并且在下次导入数据框时,它可能会增加到50行,并且在value中可能会有更多的缺失值。我需要创建一个函数,该函数能够自动检测在value处测量的缺失值,并将该特定站点的缺失值计算在内。有人能帮助我吗?

回答

10

从包plyr使用从包Hmiscimpute()ddply

require(plyr) 
require(Hmisc) 

df2 <- ddply(df, "site", mutate, imputed.value = impute(value, mean)) 
2

首先,你可以得到不同级别的网站。

sites=levels(df$site) 

然后,您可以得到不同程度的

nlevels=length(sites) 
meanlist=numeric(nlevels) 
for (i in 1:nlevels) 
    meanlist[i]=mean(df[df[,1]==sites[i],2],na.rm=TRUE) 

然后你可以在每个NA值的填补手段。可能有更快的方法,但只要你的设置不是很大,你可以用for循环来做。

for (i in 1:dim(df)[1]) 
    if (is.na(df[i,2])) 
     df[i,2]=meanlist[which(sites==df[i,1])] 

希望这会有所帮助。

2

一个解决方案在一个(是一个长的)线没有for循环。

set.seed(300) 
df <- data.frame(site = sort(rep(paste0("site", 1:5), 5)), 
       value = sample(c(1:5, NA), replace = T, 25)) 


df$value[is.na(df$value)] <- ave(df$value, df$site, 
           FUN = function(x) 
           mean(x, na.rm = TRUE))[c(which(is.na(df$value)))] 

作为一个函数:

fillITin <- function(x){ 

x$value[is.na(x$value)] <- ave(x$value, x$site, 
            FUN = function(z) 
            mean(z, na.rm = TRUE))[c(which(is.na(x$value)))] 
return(x) 
} 


fillITin(df)