2013-11-28 2 views
1

У меня есть dataframe, который выглядит следующим образом:Функции приписывать отсутствует значение

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 со значением для сайта. Поэтому, если имеется недостающее значение для value, измеренное в site1, мне необходимо ввести среднее значение value за site1. Тем не менее, dataframe постоянно добавляется и импортируется в R, и в следующий раз, когда я импортирую фреймворк данных, он, вероятно, увеличится до примерно 50 строк в длину, и в value, вероятно, будет еще много отсутствующих значений. Мне нужно сделать функцию, которая автоматически определит, на каком сайте было измерено отсутствующее значение в value, и приложите недостающее значение для этого конкретного сайта. Может ли кто-нибудь помочь мне в этом?

ответ

10

impute() Использование пакета из Hmisc и ddply из пакета plyr:

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 (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) 
Смежные вопросы