2017-02-02 6 views
2

У меня возникли проблемы с получением approx() для работы внутри mutate_at(). Мне удалось получить то, что я хочу, используя очень длинную функцию mutate(), но для будущей ссылки мне было интересно, был ли более изящный и менее скопиро- вый способ mutate_at() для этого.Как вы используете approx() внутри mutate_at()?

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

library("tidyverse") 

demodf <- data.frame(groupvar = letters[rep(1:15, each = 6)], 
        timevar = c(2000, 2003, 2006, 2009, 2012, 2015), 
        x1 = runif(n = 90, min = 0, max = 3), 
        x2 = runif(n = 90, min = -1, max = 4), 
        x3 = runif(n = 90, min = 1, max = 12), 
        x4 = runif(n = 90, min = 0, max = 30), 
        x5 = runif(n = 90, min = -2, max = 5), 
        x6 = runif(n = 90, min = 20, max = 50), 
        x7 = runif(n = 90, min = 1, max = 37), 
        x8 = runif(n = 90, min = 0.3, max = 0.5)) 

demotbl <- tbl_df(demodf) 

masterdf <- data.frame(groupvar = letters[rep(1:15, each = 17)], 
         timevar = 2000:2016, 
         z1 = runif(n = 255, min = 0, max = 1E6)) 

mastertbl <- tbl_df(masterdf) 

joineddemotbls <- mastertbl %>% left_join(demotbl, by = c("groupvar", "timevar")) 

View(joineddemotbls) 

joineddemotblswithinterpolation <- joineddemotbls %>% group_by(groupvar) %>% 
    mutate(x1i = approx(timevar, x1, timevar, rule = 2, f = 0, ties = mean, method = "linear")[["y"]], 
     x2i = approx(timevar, x2, timevar, rule = 2, f = 0, ties = mean, method = "linear")[["y"]], 
     x3i = approx(timevar, x3, timevar, rule = 2, f = 0, ties = mean, method = "linear")[["y"]], 
     x4i = approx(timevar, x4, timevar, rule = 2, f = 0, ties = mean, method = "linear")[["y"]], 
     x5i = approx(timevar, x5, timevar, rule = 2, f = 0, ties = mean, method = "linear")[["y"]], 
     x6i = approx(timevar, x6, timevar, rule = 2, f = 0, ties = mean, method = "linear")[["y"]], 
     x7i = approx(timevar, x7, timevar, rule = 2, f = 0, ties = mean, method = "linear")[["y"]], 
     x8i = approx(timevar, x8, timevar, rule = 2, f = 0, ties = mean, method = "linear")[["y"]]) 

View(joineddemotblswithinterpolation) 

# this is what I want 

Это работает очень хорошо. Но я пробовал все эти варианты mutate_at() и не получил их для работы. Я уверен, что есть ошибка в синтаксисе где-то ...

joineddemotblswithinterpolation2 <- joineddemotblswithinterpolation %>% group_by(groupvar) %>% 
    mutate_at(vars(x1, x2, x3, x4, x5, x6, x7, x8), approx(timevar, ., timevar, rule = 2, f = 0, ties = mean, method = "linear")[["y"]]) 

# error 

joineddemotblswithinterpolation2 <- joineddemotblswithinterpolation %>% group_by(groupvar) %>% 
    mutate_at(vars(x1, x2, x3, x4, x5, x6, x7, x8), approxfun(timevar, ., timevar, rule = 2, f = 0, ties = mean, method = "linear")[["y"]]) 

# error 

joineddemotblswithinterpolation2 <- joineddemotblswithinterpolation %>% group_by(groupvar) %>% 
    mutate_at(vars(x1, x2, x3, x4, x5, x6, x7, x8), funs(approxfun(timevar, ., timevar, rule = 2, f = 0, ties = mean, method = "linear")[["y"]])) 

# error 

joineddemotblswithinterpolation2 <- joineddemotblswithinterpolation %>% group_by(groupvar) %>% 
    mutate_at(vars(x1, x2, x3, x4, x5, x6, x7, x8), funs(approxfun(timevar, ., rule = 2, f = 0, ties = mean, method = "linear")[["y"]])) 

Я даже попробовал na.approx(), но также безрезультатно ...

library("zoo") 
joineddemotblswithinterpolation2 <- joineddemotblswithinterpolation %>% group_by(groupvar) %>% 
    mutate_at(vars(x1, x2, x3, x4, x5, x6, x7, x8), na.approx(., timevar, na.rm = FALSE)) 

Я вроде построены эти различные испытания из следующих взаимосвязанных вопросов:

Using approx in dplyr

Linear Interpolation using dplyr

Using approx() with groups in dplyr

linear interpolation with dplyr but skipping groups with all missing values

R: Interpolation of NAs by group

Спасибо за любую помощь!

ответ

4

Вы очень близко. Это работает для меня:

joineddemotblswithinterpolation <- joineddemotbls %>% 
    group_by(groupvar) %>% 
    mutate_at(vars(starts_with("x")), # easier than listing each column separately 
      funs("i" = approx(timevar, ., timevar, rule = 2, f = 0, ties = mean, 
           method = "linear")[["y"]])) 

Это создаст столбцы x1_i, x2_i и т.д. с интерполированными значениями.

+0

Красивая! Спасибо! – LightonGlass