Генерация новых переменных с использованием for и функции mutate в R - PullRequest
0 голосов
/ 28 августа 2018

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

fact_code style_serial ss rib button rib_s button_s
1008      style_1018   1   0  0      1     1 
1008      style_1018   0   1  0      1     1
1008      style_1018   0   1  0      1     1
1008      style_1018   0   0  1      1     1 
1008      style_1003   1   0  1      0     1
1008      style_1003   0   0  1      0     1
1008      style_1003   0   0  0      0     1
1008      style_1003   0   0  0      0     1
1004      style_1197   1   0  0      1     0 
1004      style_1197   0   0  0      1     0
1004      style_1197   0   0  0      1     0
1004      style_1197   0   1  0      1     0

Ключевые переменные, ребро и кнопка являются фиктивными переменными. Они указывают, имеет ли определенный стиль одежды, произведенный фабрикой, ребро или кнопку или оба. Затем я хочу взять максимум этих фиктивных переменных, сгруппированных по fact_code и style_serial, и в этом случае я называю их как rib_s и button_s.

Переменные rib_s и button_s были сгенерированы следующим образом:

df <- df %>% group_by(fact_code, style_serial) %>% mutate(rib_s = max(rib, na.rm = TRUE))
df <- df %>% group_by(fact_code, style_serial) %>% mutate(button_s = max(button, na.rm = TRUE))

Теперь предположим, что у меня есть около 20 таких переменных. Я хотел создать цикл, который запускается столько раз, сколько переменных и каждый раз выполняет приведенный выше код для каждой из 20 фиктивных переменных.

Я попробовал это для 2 переменных в качестве теста:

for (xx in c("rib", "button")){
df <- df %>%
group_by_(fact_code, style_serial) %>%
yy <- paste0(c(xx, "s"), collapse = "_") %>%
mutate_(yy = max(xx, na.rm = TRUE))
}

Но мне выдается следующее сообщение об ошибке:

Error in UseMethod("mutate_") : no applicable method for 'mutate_' applied to an object of class "character"

Я также пробовал использовать функции base r, например tapply и aggregate, но всегда получаю сообщения об ошибках.

У вас есть способ обойти эту проблему?

Ответы [ 2 ]

0 голосов
/ 29 августа 2018

Эту проблему можно решить очень кратко, используя dplyr::mutate_at:

library(dplyr)
key <- c("rib", "button")
df %>%
    group_by(fact_code, style_serial) %>%
    mutate_at(vars(key), funs(max = max(.)))
## A tibble: 12 x 9
## Groups:   fact_code, style_serial [3]
#   fact_code style_serial    ss   rib button rib_s button_s rib_max button_max
#       <int> <fct>        <int> <int>  <int> <int>    <int>   <dbl>      <dbl>
# 1      1008 style_1018       1     0      0     1        1      1.         1.
# 2      1008 style_1018       0     1      0     1        1      1.         1.
# 3      1008 style_1018       0     1      0     1        1      1.         1.
# 4      1008 style_1018       0     0      1     1        1      1.         1.
# 5      1008 style_1003       1     0      1     0        1      0.         1.
# 6      1008 style_1003       0     0      1     0        1      0.         1.
# 7      1008 style_1003       0     0      0     0        1      0.         1.
# 8      1008 style_1003       0     0      0     0        1      0.         1.
# 9      1004 style_1197       1     0      0     1        0      1.         0.
#10      1004 style_1197       0     0      0     1        0      1.         0.
#11      1004 style_1197       0     0      0     1        0      1.         0.
#12      1004 style_1197       0     1      0     1        0      1.         0.

Это автоматически вычисляет максимум значений (на группу) для переменных, указанных в key, и создает новые столбцы, добавляя _max к соответствующему имени столбца. Обратите внимание, что вы также можете использовать обычную семантику select (например, contains, matches, starts_with, ends_with и т. Д.) В vars(...), если вы не хотите (или не можете) определить key заранее.


Пример данных

df <- read.table(text =
    "fact_code style_serial ss rib button rib_s button_s
1008      style_1018   1   0  0      1     1
1008      style_1018   0   1  0      1     1
1008      style_1018   0   1  0      1     1
1008      style_1018   0   0  1      1     1
1008      style_1003   1   0  1      0     1
1008      style_1003   0   0  1      0     1
1008      style_1003   0   0  0      0     1
1008      style_1003   0   0  0      0     1
1004      style_1197   1   0  0      1     0
1004      style_1197   0   0  0      1     0
1004      style_1197   0   0  0      1     0
1004      style_1197   0   1  0      1     0", header = T)
0 голосов
/ 29 августа 2018

Извините, я не за своим компьютером, поэтому я не могу попытаться это исправить, но кажется, что ваш фрейм данных очень широк, когда вы хотите, чтобы он был длинным. Задумывались ли вы об использовании команды collect () для замены всех тех столбцов, которые имеют логическое значение 0 или 1, на фактическое имя столбца, значение которого равно единице?

Я думаю, что ошибка генерируется, потому что вы не можете использовать mutate в одной строке за раз. Может быть, если вы попытались сначала добавить временный столбец, а затем попытаться заполнить его внутри цикла?

...