dplyr: может ли функция, вызываемая внутри mutate, найти элемент столбца из текущей строки

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

year <- rep(1:5, times = c(2,2,2,2,2))
dat  <- 1:10
df <- tibble(year, dat)
adjust = c(rep(0, 4), rep(c(1 + 0.1*1:3), c(2,2,2)))
df %>% mutate(dat = ifelse(year < 5, year, dat*adjust[[year - 2]]))

Если мне это удастся, я получу следующую ошибку:

Evaluation error: attempt to select more than one element in vectorIndex.

Я почти уверен, что это связано с тем, что оператор извлечения [[ рассматривает year как год всего вектора, а не год текущей строки, поэтому затем происходит векторизованное вычитание, после чего [[ подавляется векторным индексом.

Я знаю, что есть много способов решить эту проблему. У меня сейчас особенно уродливый способ использования вложенных ifelse. У меня вопрос: есть ли способ сделать то, что я пытался сделать, R- и двойным идиоматическим способом? В некотором смысле это похоже на проблему с фильтром или group_by, поскольку мы хотим обрабатывать строки или группы строк как отдельные объекты, но я не нашел способа сделать это более чистым.

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

Или нет?


person andrewH    schedule 04.12.2017    source источник
comment
Как сопоставить adjust с year? У вас пять разных лет, но только три adjust значения.   -  person Psidom    schedule 04.12.2017
comment
Год сопоставляется с годом на год меньше - ну, на самом деле, меньше 3, а не 2. Позвольте мне исправить это.   -  person andrewH    schedule 04.12.2017


Ответы (1)


Вам нужно использовать [ вместо [[ для векторной индексации; А также year - 2 дает отрицательный индекс, который в дальнейшем вызовет проблемы; Если вы хотите отобразить year в adjust по позициям индекса, вы можете использовать replace с mask, который указывает year, который нужно изменить:

df %>% 
    mutate(dat = {
        mask = year > 2; 
        replace(year, mask, dat[mask] * adjust[year[mask] - 2])
    })
# A tibble: 10 x 2
#   year1  dat1
#   <int> <dbl>
# 1     1   1.0
# 2     1   1.0
# 3     2   2.0
# 4     2   2.0
# 5     3   5.5
# 6     3   6.6
# 7     4   8.4
# 8     4   9.6
# 9     5  11.7
#10     5  13.0
person Psidom    schedule 04.12.2017
comment
Спасибо Псидом! Эта функция замены очень удобна - я удивлен, что раньше с ней не сталкивался. Я просто пытался написать что-то подобное с помощью left_join. Если я дойду до этого, не гарантированно, я сравню их друг с другом и опубликую здесь результаты. - person andrewH; 04.12.2017