How to replace NA (missing values) in a data frame with neighbouring values

会有一股神秘感。 提交于 2019-11-27 10:10:16

问题


862 2006-05-19 6.241603 5.774208     
863 2006-05-20 NA       NA      
864 2006-05-21 NA       NA      
865 2006-05-22 6.383929 5.906426      
866 2006-05-23 6.782068 6.268758      
867 2006-05-24 6.534616 6.013767      
868 2006-05-25 6.370312 5.856366      
869 2006-05-26 6.225175 5.781617      
870 2006-05-27 NA       NA     

I have a data frame x like above with some NA, which i want to fill using neighboring non-NA values like for 2006-05-20 it will be avg of 19&22

How do it is the question?


回答1:


Properly formatted your data looks like this

862 2006-05-19 6.241603 5.774208 
863 2006-05-20 NA       NA 
864 2006-05-21 NA       NA 
865 2006-05-22 6.383929 5.906426 
866 2006-05-23 6.782068 6.268758 
867 2006-05-24 6.534616 6.013767 
868 2006-05-25 6.370312 5.856366 
869 2006-05-26 6.225175 5.781617 
870 2006-05-27 NA       NA

and is of a time-series nature. So I would load into an object of class zoo (from the zoo package) as that allows you to pick a number of strategies -- see below. Which one you pick depends on the nature of your data and application. In general, the field of 'figuring missing data out' is called data imputation and there is a rather large literature.

R> x <- zoo(X[,3:4], order.by=as.Date(X[,2]))
R> x
               x     y
2006-05-19 6.242 5.774
2006-05-20    NA    NA
2006-05-21    NA    NA
2006-05-22 6.384 5.906
2006-05-23 6.782 6.269
2006-05-24 6.535 6.014
2006-05-25 6.370 5.856
2006-05-26 6.225 5.782
2006-05-27    NA    NA
R> na.locf(x)  # last observation carried forward
               x     y
2006-05-19 6.242 5.774
2006-05-20 6.242 5.774
2006-05-21 6.242 5.774
2006-05-22 6.384 5.906
2006-05-23 6.782 6.269
2006-05-24 6.535 6.014
2006-05-25 6.370 5.856
2006-05-26 6.225 5.782
2006-05-27 6.225 5.782
R> na.approx(x)  # approximation based on before/after values
               x     y
2006-05-19 6.242 5.774
2006-05-20 6.289 5.818
2006-05-21 6.336 5.862
2006-05-22 6.384 5.906
2006-05-23 6.782 6.269
2006-05-24 6.535 6.014
2006-05-25 6.370 5.856
2006-05-26 6.225 5.782
R> na.spline(x)   # spline fit ...
               x     y
2006-05-19 6.242 5.774
2006-05-20 5.585 5.159
2006-05-21 5.797 5.358
2006-05-22 6.384 5.906
2006-05-23 6.782 6.269
2006-05-24 6.535 6.014
2006-05-25 6.370 5.856
2006-05-26 6.225 5.782
2006-05-27 5.973 5.716
R> 



回答2:


Depending on the data tidyr::fill() might be an option:

library(tidyverse)

df %>% fill(x)                    # single column x
df %>% fill(x, y)                 # multiple columns, x and y
df %>% fill(x, .direction = 'up') # filling from the bottom up rather than top down



回答3:


This seem to be time series, so time series missing value replacement (imputation) methods probably make sense here.

These methods look for correlations of one variable in time and estimate this missing data accordingly.

E.g. the imputeTS package might be an option here. There are multiple options:

library("imputeTS")
na_interpolation(data)

For using linear interpolation to replace the missing values.

library("imputeTS")
na_ma(data)

For using a moving average to replace the missing values.

library("imputeTS")
na_kalman(data)

A little bit more advanced for using ARIMA models/ Kalman smoothing for imputation.

There are also more possible methods (see this paper, it might make sense to dig a little bit deeper here to use the most suitable to your problem.



来源:https://stackoverflow.com/questions/1252546/how-to-replace-na-missing-values-in-a-data-frame-with-neighbouring-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!