удалите парные строки, где лаг == 0, и вычислите% изменения, используя dplyr и цепочку - PullRequest
0 голосов
/ 26 июня 2019

Я работаю с очень большим тибблом и хочу вычислить% роста этих таблиц с течением времени (первая запись до последней записи, а не от максимума до минимума). В конечном счете, я также хотел бы сохранить любые таблицы с изменением 0 в своем собственном списке / таблице, но удалить их из исходной выходной таблицы.

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

  date    tbl_name    row_cnt
2/12/2019  first       247
6/5/2019   first       247
4/24/2019  second    3617138
6/5/2019   second    3680095
3/1/2019   third    62700321
6/5/2019   third    63509189
4/24/2019  fourth       2
6/5/2019   fourth       2
...          ...       ...

и ожидаемый результат таблицы будет две таблицы, которые будут выглядеть так:

tbl_name   pct_change
second       1.74
third        1.29
...          ...


tbl_name
 first
 fourth
  ...

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

test_df <- df %>% 
  arrange(l.fully_qualf_tbl_nm) %>% 
  group_by(l.fully_qualf_tbl_nm) %>%
  filter(row_number()==1 | row_number()==n()) %>%
  mutate(pct_change = ((l.row_cnt/lag(l.row_cnt) - 1) * 100)) %>% 
  select(l.run_dt, l.fully_qualf_tbl_nm, pct_change) %>% 
  drop_na(pct_change)

но мой расчет

mutate(pct_change = ((l.row_cnt/lag(l.row_cnt) - 1) * 100)) %>%

не дает правильных результатов. Я вытащил свои вычисления pct-изменений из другого поста SO, в котором обсуждается% -change, но я получаю разные цифры из моих ручных вычислений.

Например, я получаю «second = 3,61», но ручной расчет (как и Excel) получает 1,74. Я также получаю «третий = 0,831» вместо 1,29 вручную. Я предполагаю, что я не правильно указываю, что я хочу, чтобы вычисления были выполнены только для каждой группы (каждая пара из двух строк). Мне интересно, должен ли я вычислять лаг отдельно или просто неправильно реализовываю лаг?)

далее, я думаю, что новая таблица будет создана с каким-то образом

if return value of filter(row_number()==1 | row_number()==n()) %>% == 0, append to list/table

но я, честно говоря, понятия не имею, как это сделать. Мне интересно, должен ли я просто сделать отдельную функцию и присвоить ее новой переменной.

1 Ответ

1 голос
/ 26 июня 2019
df <- read.table(
  header = T, 
  stringsAsFactors = F,
  text = " date    tbl_name    row_cnt
2/12/2019  first       247
6/5/2019   first       247
4/24/2019  second    3617138
6/5/2019   second    3680095
3/1/2019   third    62700321
6/5/2019   third    63509189
4/24/2019  fourth       2
6/5/2019   fourth       2")

# Wrapping in parentheses assigns the output to test_df and also prints it
(test_df <- df %>% 
    group_by(tbl_name) %>%
    mutate(pct_change = ((row_cnt/lag(row_cnt) - 1) * 100)) %>% 
    ungroup() %>%
    filter(!is.na(pct_change)) %>%  # Filter after pct_change calc, since we want to 
                                    # include change from 1:2  and from n-1:n
    select(tbl_name, row_cnt, pct_change))

# A tibble: 4 x 3
  tbl_name  row_cnt pct_change
  <chr>       <int>      <dbl>
1 first         247       0   
2 second    3680095       1.74
3 third    63509189       1.29
4 fourth          2       0  

Чтобы разбить на две таблицы, кажется, можно сделать:

first_tbl <- test_df %>% filter(pct_change != 0) # or "pct_change > 0" for pos growth
second_tbl <- test_df %>% filter(pct_change == 0)
...