Сортировать, вычислять и затем изменять во фрейме данных - PullRequest
0 голосов
/ 04 августа 2020

Я новичок в R, и у меня возникла проблема.

Проблема: мне нужно отсортировать фрейм данных по 2 столбцам (ID, i-й столбец), а затем взять разницу i-й столбец и запишите его. Затем обработайте данные с идентификатором и столбцом i + 1 и т. Д. И т. Д.

То, что я написал до сих пор:

for (val in (4:length(colnames(df)))){
    df <- df[with(df, order(ID, df[val])), ]
    d2_df <- df %>% 
      mutate_at(c(df[val]), list(lagged = ~ . - lag(.)))
  }

Приведенный выше код каким-то образом портит, потому что функция mutate_at выдает следующую ошибку:

Error: `.vars` must be a character/numeric vector or a `vars()` object, not a list.

Исходный набор данных:

  ID S1 S2
1 1  3  1
2 1  5  2
3 1  1  3
4 2  2  7
5 3  4  9
6 3  2  11

После сортировки по идентификатору и S1

  ID S1 S2
1 1  1  3
2 1  3  1
3 1  5  2
4 2  2  7
5 3  2  11
6 3  4  9

Что мне теперь нужно? S1.1 (который представляет собой запаздывающую разницу отсортированных фреймов данных, соответствующих каждому идентификатору)

  ID S1 S2 S1.1
1 1  1  3  NA
2 1  3  1  2
3 1  5  2  2
4 2  2  7  NA
5 3  2  11 NA
6 3  4  9  2

Аналогичный logi c применяется для S2, где будет сгенерирован новый S2.2. Любая помощь будет безмерно признательна.

Дополнительно то, что требуется (ниже); где sum.S1 - это сумма запаздывающих различий, а count.S1 - количество наблюдений в S1 для соответствующего ID:

  ID sum.S1 sum.S2 count.S1 count.S2
1 1  4      2      3        3
2 2  NA     NA     1        1
3 3  2      2      2        2

1 Ответ

1 голос
/ 04 августа 2020

Вот способ использования нестандартной оценки (NSE):

library(dplyr)
library(purrr)
library(rlang)

cols <- c('S1', 'S2')
bind_cols(df, map_dfc(cols, ~{
     col <- sym(.x)
     df %>% 
       arrange(ID, !!col) %>%
       group_by(ID) %>%
       transmute(!!paste0(.x, '.1') := !!col - lag(!!col)) %>%
       ungroup %>%
       select(-ID)
 }))


#  ID S1 S2 S1.1 S2.1
#1  1  3  1   NA   NA
#2  1  5  2    2    1
#3  1  1  3    2    1
#4  2  2  7   NA   NA
#5  3  4  9   NA   NA
#6  3  2 11    2    2

данные

df <- structure(list(ID = c(1L, 1L, 1L, 2L, 3L, 3L), S1 = c(3L, 5L, 
1L, 2L, 4L, 2L), S2 = c(1L, 2L, 3L, 7L, 9L, 11L)), 
class = "data.frame", row.names = c(NA, -6L))
...