Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NA filling using sinusoidal curve fitting

I have a data as shown below.. with one time and 2 data columns

time = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24)  
data1 = c(10, 8, NA, 3, 2, NA, 6, 8, 9, 7, NA, 3, 1, NA, 5, 7, 11, 10, NA, 5, 3, 5, NA, 8)
data2 = c(25, 20, NA, 7.5, NA,10, 15, NA, 22.5, NA, 15, 7.5, NA, 10, 12.5, 17.5, NA, 25, 17.5,NA, 7.5, 12.5, NA, 20)

I fitted a sinusoidal curve for the data1 using the code below..

Data <- data.frame(time,data1,data2)  
HR <- Data$data1  
Time <- Data$time  
xc <- cos(2*pi*Time/9)  
xs <- sin(2*pi*Time/9)  
fit.lm <- lm(HR ~ xc+xs)  
pred <- predict(fit.lm, newdata=data.frame(Time=Time))  
plot(HR ~ time, data=Data)  
lines(Time, pred, col="blue") 

The sinusoidal curve with my data1

Now I want to fill the NA values in my Data$data1 using the sine curve. Also I want to repeat the same to Data$data2..

How do I fill my NA values using this curve? Am I doing something stupid? Is there any other easyway to do this?

like image 527
Kathiravan Meeran Avatar asked Dec 07 '25 09:12

Kathiravan Meeran


1 Answers

I took the liberty of cleaning up the code and plot a more smooth fit which demonstrates how imputed values (in red) relate to that.

Data <- data.frame(time = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24) ,
                   data1 = c(10, 8, NA, 3, 2, NA, 6, 8, 9, 7, NA, 3, 1, NA, 5, 7, 11, 10, NA, 5, 3, 5, NA, 8),
                   data2 = c(25, 20, NA, 7.5, NA,10, 15, NA, 22.5, NA, 15, 7.5, NA, 10, 12.5, 17.5, NA, 25, 17.5,NA, 7.5, 12.5, NA, 20))

Data$xc <- cos(2*pi*Data$time/9)
Data$xs <- sin(2*pi*Data$time/9)

fit.lm <- lm(data1 ~ xc + xs, data = Data)  

# provide only the non-NA values to find predicted (fitted) values and write it to the result
Data$pred[!is.na(Data$data1)] <- predict(fit.lm, newdata = Data[!is.na(Data$data1), ])  
plot(data1 ~ time, data = Data)

### smooth fitted values ###
smoothP <- data.frame(time = seq(from = min(Data$time),
                                 to = max(Data$time),
                                 by = 0.1))
smoothP$xc <- cos(2*pi*smoothP$time/9)
smoothP$xs <- sin(2*pi*smoothP$time/9)

smoothP$fitted <- predict(fit.lm, newdata = smoothP)
lines(fitted ~ time, data = smoothP, col = "blue")
### end smooth fitted values ###

# predicting NAs by the same analogy as above, only this time only for NAs
Data$pred[is.na(Data$data1)] <- predict(fit.lm, newdata = Data[is.na(Data$data1), ])

points(pred ~ time, data = Data[is.na(Data$data1),], col = "red", pch = 16)

enter image description here

like image 132
Roman Luštrik Avatar answered Dec 08 '25 22:12

Roman Luštrik



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!