R выражение для управления NA при суммировании столбцов - PullRequest
5 голосов
/ 05 апреля 2011

У меня есть 5 столбцов числовых данных (m1, m2, m3, m4, m5), и я хочу создать новый столбец со средним значением всех m в той же строке. То есть:

(m1 + m2 + m3 + m4 + m5)/5

У меня проблема с управлением значениями NA: я хочу, чтобы среднее значение было NA, если и только если все индивидуальные значения m равны NA. Но если я использую na.rm, то NA заменяются нулями, и в столбце средних значений нет NA. С другой стороны, если я не использую na.rm, столбец средних значений равен NA, если ЛЮБОЙ из m есть NA.

Я сделал следующее:

m <- rowSums(data.frame(m1,m2,m3,m4,m5)/5, na.rm=TRUE)

for (i in 1:length(m)) {
    if ( all(is.na(c(m1[i],m2[i],m3[i],m4[i],m5[i])))) {
        m[i] <- NA
    }
}

Это работает, но я почти уверен, что R может сделать это лучше. Как это можно сделать без петель?

Может быть, вопрос звучит немного тривиально. Извините за это, но я новичок в R.

Заранее спасибо.

Ответы [ 2 ]

5 голосов
/ 05 апреля 2011

Используйте rowMeans вместо rowSums:

Df <- data.frame(
  m1 = c(NA,1:10,NA),
  m2 = c(10:5,NA,4:1,NA),
  m3 = c(11,12,NA,13:20,NA)
)
rowMeans(Df,na.rm=T)
[1] 10.500000  7.333333  5.000000  7.666667  8.000000  8.333333 11.000000 
    9.333333  9.666667 10.000000 10.333333        NA
3 голосов
/ 05 апреля 2011

Ответ довольно прост, и вы раскроете себя, когда я раскрою все; -)

Сначала воспроизводимый пример:

set.seed(1)
dat <- matrix(runif(100*5), ncol = 5)
## add some random NA
dat[sample(NROW(dat) * NCOL(dat), 100)] <- NA
dat <- data.frame(dat)
names(dat) <- paste("m", 1:5, sep = "")
## make 1 row all NA
dat[10, ] <- rep(NA, NCOL(dat))

Решение состоит в том, чтобы использовать rowMeans() неrowSums():

> rowMeans(dat, na.rm = TRUE)
  [1] 0.5040661 0.2447789 0.5785721 0.6552587 0.5000273 0.6553183
  [7] 0.5017969 0.5961018 0.3778305        NA 0.7843261 0.3118411
 [13] 0.6023241 0.7230658 0.4849793 0.3579792 0.5321065 0.5891246
 [19] 0.5985094 0.6450797 0.5884122 0.3308921 0.4659702 0.3595603
 [25] 0.6291160 0.5420563 0.3555441 0.3922415 0.4554090 0.6912613
 [31] 0.5849739 0.1436432 0.3363359 0.5620860 0.4845476 0.6243143
 [37] 0.6453576 0.3102552 0.6801590 0.5730385 0.6595771 0.4125847
 [43] 0.5950305 0.3908888 0.5228980 0.4290490 0.3219740 0.4941847
 [49] 0.3203416 0.6077816 0.6725149 0.6037703 0.4706785 0.3780164
 [55] 0.2773157 0.2887002 0.5679866 0.5216224 0.4181383 0.4182203
 [61] 0.3985725 0.4043380 0.3024113 0.5441925 0.6163834 0.5365182
 [67] 0.3324975 0.5444736 0.6809868 0.5073465 0.4122997 0.6164483
 [73] 0.4803133 0.3044119 0.2990064 0.5280371 0.5925953 0.6079630
 [79] 0.5144217 0.7415579 0.4059379 0.3966217 0.7344768 0.7502413
 [85] 0.4064067 0.2837371 0.6139601 0.3669062 0.5450748 0.4665940
 [91] 0.3618159 0.4623254 0.5885807 0.4686613 0.4246080 0.6322250
 [97] 0.2747088 0.4716259 0.4306550 0.1015050

Сравните запись для строки 10, используя оба подхода:

> rowMeans(dat, na.rm = TRUE)[10]
[1] NA
> rowSums(dat/5, na.rm = TRUE)[10]
[1] 0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...