Как прокрутить определенные столбцы с помощью dplyr?

Непростая общая операция для моего типа данных - это применение коэффициента нормализации ко всем столбцам. Это можно сделать эффективно с помощью sweep или scale:

normalized = scale(data, center = FALSE, scale = factors)
# or
normalized = sweep(data, 2, factors, `/`)

Где

data = structure(list(A = c(3L, 174L, 6L, 1377L, 537L, 173L),
    B = c(1L, 128L, 2L, 1019L, 424L, 139L),
    C = c(3L, 66L, 2L, 250L, 129L, 40L),
    D = c(4L, 57L, 4L, 251L, 124L, 38L)),
    .Names = c("A", "B", "C", "D"),
    class = c("tbl_df", "data.frame"), row.names = c(NA, -6L))

factors = c(A = 1, B = 1.2, C = 0.8, D = 0.75)

Однако, как мне это сделать с dplyr, когда у моих данных есть дополнительные столбцы впереди? Я могу сделать это в отдельных заявлениях, но Id нравится делать это в одном конвейере. Это мои данные:

data = structure(list(ID = c(1, 2, 3, 4, 5, 6),
    Type = c("X", "X", "X", "Y", "Y", "Y"),
    A = c(3L, 174L, 6L, 1377L, 537L, 173L),
    B = c(1L, 128L, 2L, 1019L, 424L, 139L),
    C = c(3L, 66L, 2L, 250L, 129L, 40L),
    D = c(4L, 57L, 4L, 251L, 124L, 38L)),
    .Names = c("ID", "Type", "A", "B", "C", "D"),
    class = c("tbl_df", "data.frame"), row.names = c(NA, -6L))

И Id нравится мутировать столбцы данных, не касаясь первых двух столбцов. Обычно я могу сделать это с помощью mutate_each; однако, как я не могу передать свои коэффициенты нормировки для этой функции:

data %>% mutate_each(funs(. / factors), A:D)

Это, что неудивительно, предполагает, что я хочу разделить каждый столбец на factors, а не на каждый столбец по его коэффициенту соответствия.

Ответ 1

Учитывая акрунскую поддержку, позвольте мне опубликовать здесь то, что я сделал, в качестве ответа. Я просто интуитивно подумал, что вы можете попросить R указать столбцы с тем же именем, чтобы сделать это mutate_each. Например, если . указывает на столбец A, я подумал, что другой столбец с именем A из другого data.frame может быть чем-то, что может понравиться dplyr. Итак, я создал фрейм данных для factors затем использовал mutate_each. Похоже, что результат правильный. Поскольку у меня нет технической подготовки, я боюсь, что не могу дать никаких объяснений. Надеюсь, ты не против.

factors <- data.frame(A = 1, B = 1.2, C = 0.8, D = 0.75)

mutate_at(data, vars(A:D), funs(. / foo$.))

# By the time I answered this question, the following was working.
# But mutate_each() is now deprecated.

# mutate_each(data, funs(. / factors$.), A:D)

#  ID Type    A           B      C          D
#1  1    X    3   0.8333333   3.75   5.333333
#2  2    X  174 106.6666667  82.50  76.000000
#3  3    X    6   1.6666667   2.50   5.333333
#4  4    Y 1377 849.1666667 312.50 334.666667
#5  5    Y  537 353.3333333 161.25 165.333333
#6  6    Y  173 115.8333333  50.00  50.666667

РЕДАКТИРОВАТЬ

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

# Experiment
foo <- list(A = 1, B = 1.2, C = 0.8, D = 0.75)

mutate_at(data, vars(A:D), funs(. / foo$.))

# mutate_each(data, funs(. / foo$.), A:D)

#  ID Type    A           B      C          D
#1  1    X    3   0.8333333   3.75   5.333333
#2  2    X  174 106.6666667  82.50  76.000000
#3  3    X    6   1.6666667   2.50   5.333333
#4  4    Y 1377 849.1666667 312.50 334.666667
#5  5    Y  537 353.3333333 161.25 165.333333
#6  6    Y  173 115.8333333  50.00  50.666667