Как использовать tapply и сохранить порядок значений - PullRequest
6 голосов
/ 24 мая 2011

надеюсь, это не слишком глупый вопрос, но, будучи новичком в R, у меня возникла серьезная проблема с tapply. Скажем

factors <- as.factor( c("a", "b", "c", "a", "b", "c", "a", "b", "c") )
values  <- c( 1, 2, 3, 4, 5, NA, 7, NA, NA )
tapply(
  values,
  factors,
  function(x){
    if( sum(is.na(x)) == 1 ){
      x[ is.na(x) ] <- 0
    }
    return(x)
  }
)

Результат

$a
[1] 1 4 7

$b
[1] 2 5 0

$c
[1]  3 NA NA

Тем не менее, мне нужно вернуть вектор, который сохраняет исходный порядок значений, т.е.

c( 1,2,3,4,5,NA,7,0,NA )

Большое спасибо заранее.

Ответы [ 3 ]

7 голосов
/ 24 мая 2011

В этом случае вы должны использовать функцию ave:

> ave(values, factors, FUN=function(x) {
+     if( sum(is.na(x)) == 1 ){
+       x[ is.na(x) ] <- 0
+     }
+     return(x)
+   }
+ )
[1]  1  2  3  4  5 NA  7  0 NA
1 голос
/ 24 мая 2011

Простой цикл for делает это очень просто:

fun <- function(x){
   if(sum(is.na(x)) == 1){x[is.na(x)] <- 0}
       return(x)
}

for (i in unique(factors)){
   values[i == factors] <- fun(values[i == factors])
}
0 голосов
/ 24 мая 2011

Можно использовать метод замены для split ():

## create a copy to store the result after replacement
res <- values

## use split's replacement method to split, apply, and recombine
split(res, factors) <- lapply(split(res, factors),
 function(x){
 if( sum(is.na(x)) == 1 ){
   x[ is.na(x) ] <- 0
 }
  return(x)
 }
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...