Итеративно вычитать векторы в кадре данных - PullRequest
0 голосов
/ 18 сентября 2018

Есть похожие вопросы, но я уверен, что этот вопрос уникален.

У меня большой массив данных с переменными, которые включают числовые векторы и различные идентификаторы.

> dataframe
 ID    ID.2    vectors  
  1     a       c(6, 3, 7, 4, 7, 2, 6)
  1     a       c(4, 7, 2, 7, 4, 7, 8) 
  2     a       c(5, 8, 2, 7, 8, 9, 9)
  2     a       c(6, 9, 7, 2, 6, 8, 9)
  1     b       c(4, 8, 2, 6, 8, 9, 0)
  1     b       c(5, 8, 2, 7, 8, 9, 9)

Мне нужно перебрать кадр данных и найти разницу между векторами по переменным идентификаторам.Таким образом, вывод из поддельных данных выше должен выглядеть следующим образом:

> dataframe$difference
c(2, -4, 5, -3, 3, -5, -2)
NA # because difference has been found
c(-1, -1, -4, 5, 2, 1, 0)
NA
c(-1, 0, 0, -1, 0, 0, -9)
NA

Это было (на удивление) сложно понять.Заранее спасибо.

1 Ответ

0 голосов
/ 18 сентября 2018

Если бы это было для отдельных чисел, вы могли бы использовать diff, но для столбца списка (предположительно) векторов вам пришлось бы прибегать к операциям со списком, таким как purrr::accumulate (для последовательного вычитания) или purrr::map2 (для попарных). dplyr::lead сместится на единицу вверх и вставит NA s.

library(tidyverse)

df <- data_frame(ID = c(1L, 1L, 2L, 2L, 1L, 1L), 
                 ID.2 = c("a", "a", "a", "a", "b", "b"), 
                 vectors = list(c(6, 3, 7, 4, 7, 2, 6), c(4, 7, 2, 7, 4, 7, 8), c(5, 8, 2, 7, 8, 9, 9), c(6, 9, 7, 2, 6, 8, 9), c(4, 8, 2, 6, 8, 9, 0), c(5, 8, 2, 7, 8, 9, 9)))

df %>% 
    group_by(ID, ID.2) %>% 
    mutate(diff = map2(vectors, lead(vectors), `-`)) %>% 
    as.data.frame()    # for printing
#>   ID ID.2             vectors                       diff
#> 1  1    a 6, 3, 7, 4, 7, 2, 6    2, -4, 5, -3, 3, -5, -2
#> 2  1    a 4, 7, 2, 7, 4, 7, 8 NA, NA, NA, NA, NA, NA, NA
#> 3  2    a 5, 8, 2, 7, 8, 9, 9     -1, -1, -5, 5, 2, 1, 0
#> 4  2    a 6, 9, 7, 2, 6, 8, 9 NA, NA, NA, NA, NA, NA, NA
#> 5  1    b 4, 8, 2, 6, 8, 9, 0     -1, 0, 0, -1, 0, 0, -9
#> 6  1    b 5, 8, 2, 7, 8, 9, 9 NA, NA, NA, NA, NA, NA, NA
...