Суммируем последние n значений, отличных от NA, в каждом столбце матрицы в R

#r

#r

Вопрос:

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

 x1<-c(1,2,3,4,5,6,NA)
x2<-c(1,2,NA,4,5,NA,NA)
x3<-c(1,2,3,4,NA,NA,NA)
x4<-c(1,2,3,NA,NA,NA,NA)
x5<-c(1,2,NA,NA,NA,NA,NA)
x<-cbind(x1,x2,x3,x4,x5)
  

Если я хочу вычислить последние 3 значения, отличных от NA, в каждом столбце, и если в столбце меньше 3 значений, отличных от NA (например, столбец 5), то я суммирую все значения, отличные от NA, в этом столбце. Я хочу, чтобы результат выглядел как

 15 11 10 6 3
  

Спасибо!

Комментарии:

1. Является ли значение для 3-го столбца 10 или 9 ?

2. Должно быть 9. Хороший улов!

Ответ №1:

Вы можете использовать apply with tail для суммирования последних не NA значений, подобных:

 apply(x, 2, function(x) sum(tail(x[!is.na(x)], 3)))
#x1 x2 x3 x4 x5 
#15 11  9  6  3 
  

Ответ №2:

Это также работает с настраиваемой функцией (ответ @ GKi довольно классный):

 #Build function
myfun <- function(y)
{
  #Count na
  i <- length(which(!is.na(y)))
  if(i<3)
  {
    r1 <- sum(y,na.rm=T)
  } else
  {
    y1 <- y[!is.na(y)]
    y2 <- y1[(length(y1)-2):length(y1)]
    r1 <- sum(y2)
  }
  return(r1)
}
#Apply
apply(x,2,myfun)
  

Вывод:

 x1 x2 x3 x4 x5 
15 11  9  6  3
  

Ответ №3:

Одним dplyr вариантом, использующим логику из @GKi, может быть:

 x %>%
 data.frame() %>%
 summarise(across(everything(), ~ sum(tail(na.omit(.), 3))))

  x1 x2 x3 x4 x5
1 15 11  9  6  3
  

Или:

 x %>%
 data.frame() %>%
 summarise(across(everything(), ~ sum(rev(na.omit(.))[1:3], na.rm = TRUE)))
  

Ответ №4:

Используя sapply из base R

 sapply(as.data.frame(x), function(x) sum(tail(na.omit(x), 3)))
# x1 x2 x3 x4 x5 
#15 11  9  6  3