I have a matrix that looks like below:
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)
If I want to calculate the last 3 non NA values of each column, and if a column has less than 3 non NA values (like column 5), then I'll sum all the non NA values in that column. I want an output that looks like
15 11 10 6 3
Thank you!
You can use apply
with tail
to sum up the last non NA
like:
apply(x, 2, function(x) sum(tail(x[!is.na(x)], 3)))
#x1 x2 x3 x4 x5
#15 11 9 6 3
It also works with a customized function (@GKi answer is pretty cool):
#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)
Output:
x1 x2 x3 x4 x5
15 11 9 6 3
One dplyr
option using the logic from @GKi could be:
x %>%
data.frame() %>%
summarise(across(everything(), ~ sum(tail(na.omit(.), 3))))
x1 x2 x3 x4 x5
1 15 11 9 6 3
Or:
x %>%
data.frame() %>%
summarise(across(everything(), ~ sum(rev(na.omit(.))[1:3], na.rm = TRUE)))
Using sapply
from 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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.