Reputation: 483
I would like to create a function using this as base:
locf <- function(x) {
a <- x[1]
for (i in 2:length(x)) {
if (is.na(x[i])) x[i] <- a
else a <- x[i]
}
return(x)
}
This function is just LOCF, I would like to create a function that is LOCF for all the missing data and NOCB for the first missing observation.
My data:
data<-c(NA, 24.107, NA, 26.912, NA, 30.193, NA, 19.003, NA, NA, 28.578, NA, NA, 33.484, 32.952, 13.574, NA, NA, 38.782, NA, NA, NA, 28.804, NA, 27.042, NA, NA, NA, NA, 21.344, NA, 21.507, NA, NA, NA, 16.508, NA, NA, 14.015, 11.738, 15.055)
What i want to obtain:
locf<-c(24.107, 24.107, 24.107, 26.912, 26.912, 30.193, 30.193, 19.003, 19.003, 19.003, 28.578, 28.578, 28.578, 33.484, 32.952, 13.574, 13.574, 13.574, 38.782, 38.782, 38.782, 38.782, 28.804, 28.804, 27.042, 27.042, 27.042, 27.042, 27.042, 21.344, 21.344, 21.507, 21.507, 21.507, 21.507, 16.508, 16.508, 16.508, 14.015, 11.738, 15.055)
Thank you in advance.
Upvotes: 0
Views: 787
Reputation: 7730
Exactly this function exists in the imputeTS package:
library(imputeTS)
imputeTS::na.locf(x, option = "locf", na.remaining = "rev")
With the na.remaining parameter you can choose what shall be done with the remaining trailing NAs. You can for choose between "rev" (reverse), "mean" or "keep". Choosing "rev" does nocb for all NAs at the beginning that could not be filled by locf. If you choose to do option = "nocb" instead of "locf" in the first place it would of course then fill the trailing NAs with "locf".
Upvotes: 0
Reputation: 263332
This sets the first na to be the next value and then resets subsequent na’s by their locf values.
#library(zoo)
Nocb1.locf <- function (x){ wh1st <- which(is.na(x))[1];
x[wh1st] <- x[wh1st + 1]
x <- zoo::na.locf(x) }
Upvotes: 1
Reputation: 2856
If you refer to the first element of the list by "first missing observation", the following would work:
my_function <- function(my_list) {
for(i in 1:length(my_list)) {
if(is.na(my_list[i])) {
if(i == 1) {
my_list[i] <- my_list[i + 1]
} else {
print(i)
my_list[i] <- my_list[i - 1]
}
}
}
return(my_list)
}
If you want to treat the first NA observation of the list differently regardless of its location (i.e. it may be third element of the list overall), you can tweak the function:
my_function <- function(my_list) {
first <- 0
for(i in 1:length(my_list)) {
if(is.na(my_list[i])) {
if(first == 0) {
my_list[i] <- my_list[i + 1]
first <- 1
} else {
print(i)
my_list[i] <- my_list[i - 1]
}
}
}
return(my_list)
}
Upvotes: 1