2015-01-13 3 views
3

Я пытаюсь использовать функцию na.approx() из библиотеки zoo (в сочетании с xts) для интерполяции отсутствующих значений из данных повторных измерений для нескольких лиц с несколькими измерениями.Линейная интерполяция с использованием dplyr

Выборочные данные ...

event.date <- c("2010-05-25", "2010-09-10", "2011-05-13", "2012-03-28", "2013-03-07",  
       "2014-02-13", "2010-06-11", "2010-09-10", "2011-05-13", "2012-03-28", 
       "2013-03-07", "2014-02-13") 
variable <- c("neck.bmd", "neck.bmd", "neck.bmd", "neck.bmd", "neck.bmd", "neck.bmd", 
       "wbody.bmd", "wbody.bmd", "wbody.bmd", "wbody.bmd", "wbody.bmd", "wbody.bmd") 
value  <- c(0.7490, 0.7615, 0.7900, 0.7730, NA, 0.7420, 1.0520, 1.0665, 1.0760, 
       1.0870, NA, 1.0550) 
## Bind into a data frame 
df <- data.frame(event.date, variable, value) 
rm(event.date, variable, value) 
## Convert date 
df$event.date <- as.Date(df$event.date) 
## Load libraries 
library(magrittr) 
library(xts) 
library(zoo) 

я могу интерполировать одну недостающую точку данных для одного результата для данного человека с помощью xts() и na.approx() ....

## Subset one variable 
wbody <- subset(df, variable == "wbody.bmd") 
## order/index and then interpolate 
xts(wbody$value, wbody$event.date) %>% 
    na.approx() 
2010-06-11 1.052000 
2010-09-10 1.066500 
2011-05-13 1.076000 
2012-03-28 1.087000 
2013-03-07 1.070977 
2014-02-13 1.055000 

Не идеал, имеющий матрица вернулась, но я могу обойти это. Основная проблема, которую я имею, заключается в том, что у меня много результатов для нескольких людей. Я, возможно, наивно полагал, что, так как это, следовательно, разделенным применить-скомбинировать проблему, которую я мог бы утилизировать dplyr для достижения этой цели следующим образом ...

## Load library 
library(dplyr) 
## group and then arrange the data (to ensure dates are correct) 
df %>% 
    group_by(variable) %>% 
    arrange(variable, event.date) %>% 
     xts(.$value, .$event.date) %>% 
     na.approx() 
Error in xts(., .$value, .$event.date) : 
    order.by requires an appropriate time-based object 

Кажется, что dplyr не очень хорошо играть с xts/zoo, и я потратил пару часов на поиски, чтобы найти учебники/примеры того, как интерполировать недостающие точки данных в R, но все, что я нашел, это примеры из одного примера, и до сих пор мне не удалось найти ничего о том, как сделать это для нескольких сайтов для нескольких людей (я понимаю, что я мог бы сделать это просто проблемой нескольких людей, изменив мои данные до широкого, но это все равно не решит проблему, с которой я сталкиваюсь).

Любые мысли/советы/идеи о том, как действовать, будут очень признательны.

Благодаря

EDIT: Разъяснение того, что некоторые функции приходят из zoo пакета.

+2

Я не знаком с 'xts', но, возможно, вы ищите это: 'df%>% group_by (variable)%>% arr (переменная, event.date)%>% mutate (значение = na.approx (значение))' где na.approx из пакета zoo. Если вы хотите изменить столбцы с помощью dplyr, вы обычно делаете это в вызове 'mutate' или, если вы производите произвольные функции, внутри' do'. –

+0

AFAIK, там нет 'na.approx' в xts (только что установлен) –

+0

@slackline, код в моем первом комментарии делает то, что вы ожидали? –

ответ

4

Решение я пошел с на основе первого комментария от @docendodiscimus

Вместо того, чтобы пытаться создать новый кадр данных, как я делал этот подход просто добавляет столбцы в существующий фрейм данных с помощью воспользовавшись функцией dplyrmutate().

Мой код теперь ...

df %>% 
    group_by(variable) %>% 
    arrange(variable, event.date) %>% 
     mutate(ip.value = na.approx(value, maxgap = 4, rule = 2)) 

maxgap позволяет UPTO четыре последовательных NA «с, в то время как вариант rule позволяет экстраполировать в фланговых моменты времени.

3

Используйте функцию approx() для линейной интерполяции:

df %>% 
    group_by(variable) %>% 
    arrange(variable, event.date) %>% 
    mutate(time=seq(1,n())) %>% 
     mutate(ip.value=approx(time,value,time)$y) %>% 
     select(-time) 

или функции spline для нелинейной интерполяции:

df %>% 
    group_by(variable) %>% 
    arrange(variable, event.date) %>% 
    mutate(time=seq(1,n())) %>% 
     mutate(ip.value=spline(time,value ,n=n())$y) %>% 
     select(-time) 
Смежные вопросы