2012-02-17 13 views
12

私は、サンショウウオの腸から様々な節足動物の長さと幅を持つデータフレームを持っています。いくつかの腸には何千種類もの獲物があるので、私は各獲物の種類のサブセットを測定しました。私は今、それぞれの測定されていない個体を、その獲物の平均の長さと幅で置き換えたいと思っています。私はデータフレームを保持し、帰属列(length2、width2)を追加したい。主な理由は、各列には、サラマンダーが収集された日付と場所のデータを含む列もあります。測定された個体を無作為に選択してNAを記入することもできますが、議論のために各NAを平均値に置き換えたいと仮定します。実際にはNAをRの部分集合で置き換えるにはどうすればいいですか?

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やプログラミングに精通していないが、私は学びたいと思っている。

私は何をしているのか分かりませんが、役立つ場合は小さなデータセットを作成しようとします。ここで

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)) 
    }) 

任意の提案はplyrを使用していませんか?

+7

あなたが値を帰するためにパッケージ*マウス*を検討すべきです。 –

+1

'mi'パッケージもかなり良いです。 'Amelia'は' mice'や 'mi'よりもはるかに速いですが、あなたの変数が多変量正規であることに頼っています – richiemorrisroe

答えて

37

私はしばらく前にボード上でそれを見ていない私自身の技術:

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 apローチ:

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) 
    ) 
+3

@djhocking Hadleyに感謝します。私はこれをどこから盗んだのか分かりました:http:// www.mail-archive.com/[email protected]/msg58289.html) –

2

これに答える前に、私は、そこでRの初心者ですと言ってくださいしたいです私の答えが間違っていると感じたら教えてください。

コード:

DF[is.na(DF$length), "length"] <- mean(na.omit(telecom_original_1$length)) 

と幅のために同じことを適用します。

DFは、data.frameの名前を表します。

おかげで、@Tyler Rinkerのソリューションを拡張し Parthi

0

は、featuresを転嫁する列あるとします。この場合、features <- c('length', 'width')。そして、data.tableを使用するソリューションは次のようになります。

library(data.table) 
setDT(dat) 

dat[, (features) := lapply(.SD, impute.mean), by = taxa, .SDcols = features] 
関連する問題