Отфильтруйте все столбцы во временных рядах, чтобы сохранить только верх 1/3 - PullRequest
1 голос
/ 14 марта 2019

У меня есть временной ряд с около 100 датами, 50 объектами на дату (таким образом, 5000 строк) и 50 столбцами (все это разные переменные). Как я могу отфильтровать каждый столбец во фрейме данных по уникальной дате, чтобы сохранить верхние 1/3 значений для каждого столбца на каждую дату. Затем получите средний доход для этой группы на эту дату. Спасибо.

Мои данные организованы следующим образом, но числа в каждом столбце случайны и различаются, как и в столбце «а» (это пример, реальные данные имеют гораздо больше столбцов и много строк):

Date      Identity       Return   a     b     c    d     e      f... ...z
2/1/19        X                5      75   43     67   85    72     56     92
2/1/19        Y                4      27   43     67   85    72     56     92
2/1/19        Z                7      88   43     67   85    72     56     92
2/1/19        W               2      55   43     67   85    72     56     92
2/2/19         X               7      69   43     67   85    72     56     92
2/2/19         Y               8      23   43     67   85    72     56     92
2/3/19         X                2      34   43     67   85    72     56     92
2/3/19         Y                3      56   43     67   85    72     56     92
2/3/19         Z                4      62   43     67   85    72     56     92
2/3/19         W               4      43   43     67   85    72     56     92
2/3/19         U                4      26   43     67   85    72     56     92
2/4/19         X                6      67   43     67   85    72     56     92
2/4/19         Y                1      78   43     67   85    72     56     92
2/5/19         X                4      75   43     67   85    72     56     92
2/7/19         X                5      99   43     67   85    72     56     92
2/7/19         Y                 4      72   43     67   85    72     56     92
2/7/19         Z                  4      45   43     67   85    72     56     92

Я пытаюсь отфильтровать данные в квантили. У меня есть код, который работает для фильтрации в квантилях за одну меру. Однако я хочу отфильтровать результаты по многим показателям индивидуально (т. Е. Мне нужна «высокая» группа для тонны столбцов).

Код, который у меня работает для одной меры, выглядит следующим образом.

Столбцы - это дата, идентификатор, а a - индикатор, по которому я хочу отсортировать

High = df[!is.na(df$a),] %>%
    group_by(df.date) %>% 
    filter(a > quantile(a, .666)) %>%
    summarise(high_return = sum(df.return) / length(df.identity)

Теперь я хочу повторить это, когда у меня есть много индикаторов для сортировки по отдельности (т.е. я не хочу сортировать друг в друге, я хочу, чтобы каждый сортировался отдельно, а результаты разбивались по индикаторам)

Я хочу, чтобы вывод цикла представлял собой новый фрейм данных в следующем формате (где a_Return - это среднее возвращение верхних 1/3 оригинальных a на данную дату):

Date       a_Return    b_Return    c_Return
2/1/19       6.            7           3
2/3/19       4.            2           5
2/4/19       2.            4           6

Я попробовал приведенный ниже код, но он не работает:

Indicators <- c(“a”, “b”, “c”)

for(i in 1:length(Indicators)){
     High = df %>%
        group_by(df.date) %>% 
        filter(High[[I]] > quantile(High[[i]], .666)) %>%
        summarise(g = sum(df.return) / length(df.identity)}

При этой попытке я получаю ошибку: «Ошибка в filter_impl (.data, quo): результат должен иметь длину 20, а не 4719.

»

Я тоже пробовал:

High %>%
    group_by(date) %>%
    filter_at(vars(Indicators[i]), any_vars(. > quantile (., .666)))%>%
    summarise(!!Indicators[I] := sum(Return) / n())

но с этим кодом я получаю ошибку "Строки должны совпадать с именами столбцов. Неизвестные столбцы: нет"

Я хочу, чтобы High поднялся со столбцом даты, а затем столбцом для каждого a, b и c.

1 Ответ

0 голосов
/ 14 марта 2019

Если вы объединяете фильтрацию и вычисления в одну функцию, вы можете поместить ее в summarize_at, чтобы легко применить ее к каждому столбцу. Поскольку данные в вашем примере не полностью воспроизводимы, я буду использовать набор данных iris. В вашем случае вы бы заменили Species на Date, а Petal.Width на Return:

library(dplyr)
top_iris <- iris %>%
    group_by(Species) %>%
    summarize_at(vars(one_of('Sepal.Length', 'Sepal.Width', 'Petal.Length')),
                 funs(return = sum(Petal.Width[. > quantile(., .666)]) / length(Petal.Width[. > quantile(., .666)])))

top_iris

# A tibble: 3 x 4
  Species    Sepal.Length_return Sepal.Width_return Petal.Length_return
  <fct>                    <dbl>              <dbl>               <dbl>
1 setosa                   0.257              0.262               0.308
2 versicolor               1.44               1.49                1.49 
3 virginica                2.1                2.22                2.09 

Проблема с использованием filter состоит в том, что каждая функция в конвейере работает по порядку, поэтому любые критерии, которые вы задаете для filter_*, должны быть применены ко всему фрейму data.frame, прежде чем результат будет передан в summarize_at , Вместо этого мы просто используем один оператор summarize_at и фильтруем каждый столбец, когда к нему применяется функция суммирования.


Чтобы объяснить это более подробно, summarize_at принимает 2 аргумента:

Первый аргумент - это одна или несколько функций выбора переменных, описанных в ?select_helpers, заключенных в функцию vars. Здесь мы используем one_of, который просто берет вектор имен столбцов, но мы также можем использовать matches для выбора с использованием регулярного выражения или starts_with для выбора на основе префикса, например.

Второй аргумент - это список из одного или нескольких вызовов функций, которые должны выполняться в каждом выбранном столбце, заключенный в функцию funs. Здесь у нас есть 1 вызов функции, которому мы дали имя return.

Как и для любой функции tidyverse, она оценивается в локальной среде, созданной из данных, переданных по каналу. Таким образом, имена переменных, например Petal.Width, обозначают data$Petal.Width. В функциях *_at . представляет переданную переменную, поэтому при суммировании столбца Sepal.Length:

Petal.Width[. > quantile(., .666)]

означает:

data$Petal.Width[data$Sepal.Length > quantile(data$Sepal.Length, .666)]

Наконец, так как функция в funs названа (это return =), то результирующие итоговые столбцы имеют имя функции (return), добавленное к исходным именам столбцов.


Если вы хотите удалить отсутствующие данные перед выполнением этих вычислений, вы можете использовать na.omit, чтобы убрать NA значений.

Чтобы удалить все строки , содержащие NA, просто передайте данные через na.omit перед группировкой:

iris2 <- iris
iris2[c(143:149), c(1:2)] <- NA

iris2 %>%
    na.omit() %>%
    group_by(Species) %>%
    summarize_at(vars(one_of('Sepal.Length', 'Sepal.Width', 'Petal.Length')),
                 funs(return = sum(Petal.Width[. > quantile(., .666)]) / length(Petal.Width[. > quantile(., .666)])))

  Species    Sepal.Length_return Sepal.Width_return Petal.Length_return
  <fct>                    <dbl>              <dbl>               <dbl>
1 setosa                   0.257              0.262               0.308
2 versicolor               1.44               1.49                1.49 
3 virginica                2.09               2.19                2.07 

Чтобы убрать NA значений из каждого столбца во время суммирования, вам нужно переместить na.omit внутри функции суммирования:

iris2 %>%
    group_by(Species) %>%
    summarize_at(vars(one_of('Sepal.Length', 'Sepal.Width', 'Petal.Length')),
                 funs(return = {
                     var <- na.omit(.)
                     length(Petal.Width[var > quantile(var, .666)])
                 }))
# A tibble: 3 x 4
  Species    Sepal.Length_return Sepal.Width_return Petal.Length_return
  <fct>                    <dbl>              <dbl>               <dbl>
1 setosa                   0.257              0.262               0.308
2 versicolor               1.44               1.49                1.49 
3 virginica                2.11               2.2                 2.09 

Здесь мы используем фигурные скобки, чтобы расширить функцию, которую мы запускаем в summarize_at, на несколько выражений. Сначала мы удаляем NA значений, затем вычисляем возвращаемые значения. Поскольку эта функция находится в summarize_at, она применяется к каждой переменной на основе группировки, установленной group_by.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...