Как я могу изменить многие столбцы в dplyr, не повторяя много раз? - PullRequest
0 голосов
/ 16 января 2019

Я нахожусь в процессе написания очень неСУХОЙ цепочки dplyr в R. Мне нужно вызвать dplyr::mutate() and dplyr::percent_rank() функцию для большого количества столбцов из моего фрейма данных, и это было бы полезно для меня не иметь строки кода для каждого вызова. Мои столбцы данных, для которых мне нужно вычислить процентили, имеют следующий шаблон:

regions <- c("atr2", "sht2", "mid2", "lng2", "all2", "sht3", "lng3", "all3")
suffixes <- c("Made", "Att", "AttFreq", "Pct")
for(i in regions) {
  for(j in suffixes) {
    print(paste0(i, j))
  }
}

В приведенном выше примере мне нужно 8 * 4 == 32 разные процентильные столбцы. Все 32 начальных столбца atr2Made, atr2Att и т. Д. Уже находятся в моем фрейме данных. Чтобы вычислить процентили, я делал следующее:

pctile.lineup.data <- pctile.lineup.data %>%
    dplyr::group_by(season) %>%
    # dplyr::group_by(season, homeConfId) %>%
    dplyr::mutate(atr2MadeRankNcaa = round(100 * dplyr::percent_rank(atr2Made))) %>%
    dplyr::mutate(atrAttRankNcaa = round(100 * dplyr::percent_rank(atr2Att))) %>%
    dplyr::mutate(atr2AttFreqRankNcaa = round(100 * dplyr::percent_rank(atr2AttFreq))) %>%
    dplyr::mutate(atr2PctRankNcaa = round(100 * dplyr::percent_rank(atr2Pct))) %>%
    dplyr::mutate(sht2MadeRankNcaa = round(100 * dplyr::percent_rank(sht2Made))) %>%
    dplyr::mutate(shtAttRankNcaa = round(100 * dplyr::percent_rank(sht2Att))) %>%
    dplyr::mutate(sht2AttFreqRankNcaa = round(100 * dplyr::percent_rank(sht2AttFreq))) %>%
    dplyr::mutate(sht2PctRankNcaa = round(100 * dplyr::percent_rank(sht2Pct))) %>%
    dplyr::mutate(mid2MadeRankNcaa = round(100 * dplyr::percent_rank(mid2Made))) %>%
    dplyr::mutate(midAttRankNcaa = round(100 * dplyr::percent_rank(mid2Att))) %>%
    dplyr::mutate(mid2AttFreqRankNcaa = round(100 * dplyr::percent_rank(mid2AttFreq))) %>%
    dplyr::mutate(mid2PctRankNcaa = round(100 * dplyr::percent_rank(mid2Pct))) %>%
    ... %>%
    dplyr::ungroup()

Мне нужны не только 32 разные функции mutate(), мне нужно дважды запустить этот код для двух разных group_by() с (см. 2-ю закомментированную). Есть ли лучший способ, чем 64 строки кода? У меня есть отдельный элемент данных, который имеет 21 регион вместо 8, с теми же 4 суффиксами и теми же 2 group_by (), поэтому для вычисления этих процентилей потребуется 21 * 4 * 2 == 168 строк кода. Это не СУХОЙ - пожалуйста, помогите!

Редактировать: Я, очевидно, изучаю mutate_at, однако я не очень хорошо знаком с версией _at mutate. В моем фрейме данных есть и другие столбцы, кроме этих 32, и я не думаю, что mutate_all будет работать.

1 Ответ

0 голосов
/ 17 января 2019

Это именно то, для чего dplyr::mutate_at. Начиная с некоторых примеров данных:

df <- data.frame(name = LETTERS[1:5],
                 item1 = rnorm(5, mean=2),
                 item2 = rnorm(5, mean=5),
                 item3 = rnorm(5, mean=7))

Функции *_at принимают 2 аргумента:

  • a .vars аргумент, который принимает функции селектора, используемые dplyr::select. В этом случае мы используем one_of для предоставления списка переменных, но мы могли бы упростить это, используя contains или starts_with, если есть переменные для
  • a .funs аргумент, где мы помещаем функцию, которая будет применена к каждому из этих столбцов.

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

df %>%
    mutate_at(.vars = vars(one_of('item1', 'item2')),
              .funs = funs(rounded = round(100 * percent_rank(.)))   

  name    item1    item2    item3 item1_rounded item2_rounded
1    A 3.801373 5.701111 9.871991           100            75
2    B 2.264733 5.730916 8.558700            25           100
3    C 3.432726 5.623918 7.359317            75            50
4    D 2.137491 5.286736 7.996114             0            25
5    E 3.227416 5.269252 6.588257            50             0

Поскольку функция в .funs названа (rounded = ...), результат этой операции преобразуется в новые переменные с суффиксом с этим именем. Если бы оно было безымянным, то выбранные переменные были бы изменены сами (то есть item1 и item2 были бы заменены на округленные версии)

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