mutate_at не создает переменные суффиксы в некоторых случаях?
Я играл с dplyr::mutate_at
создать новые переменные, применив ту же функцию к некоторым столбцам. Когда я называю свою функцию в .funs
В качестве аргумента, вызов mutate создает новые столбцы с суффиксом вместо замены существующих, что является отличным вариантом, который я обнаружил в этой теме.
df = data.frame(var1=1:2, var2=4:5, other=9)
df %>% mutate_at(vars(contains("var")), .funs=funs('sqrt'=sqrt))
#### var1 var2 other var1_sqrt var2_sqrt
#### 1 1 4 9 1.000000 2.000000
#### 2 2 5 9 1.414214 2.236068
Тем не менее, я заметил, что когда vars
Аргумент, используемый для указания моих столбцов, возвращает только один столбец вместо нескольких, полученный новый столбец удаляет исходное имя: ему присваивается имя sqrt
вместо other_sqrt
Вот:
df %>% mutate_at(vars(contains("other")), .funs=funs('sqrt'=sqrt))
#### var1 var2 other sqrt
#### 1 1 4 9 3
#### 2 2 5 9 3
Я хотел бы понять, почему такое поведение происходит, и как его избежать, потому что я не знаю заранее, сколько столбцов contains()
вернусь.
РЕДАКТИРОВАТЬ: Вновь созданные столбцы должны наследовать исходное имя исходных столбцов, а также суффикс "sqrt" в конце.
Спасибо
2 ответа
Вот еще одна идея. Мы можем добавить setNames(sub("^sqrt$", "other_sqrt", names(.)))
после mutate_at
вызов. Идея состоит в том, чтобы заменить имя столбца sqrt
с other_sqrt
, Шаблон ^sqrt$
должен соответствовать только производный столбец sqrt
если есть только один столбец с именем other
Это показано в примере 1. Если имеется более одного столбца с other
такой как Пример 2, setNames
не будет изменять имена столбцов.
library(dplyr)
# Example 1
df <- data.frame(var1 = 1:2, var2 = 4:5, other = 9)
df %>%
mutate_at(vars(contains("other")), funs("sqrt" = sqrt(.))) %>%
setNames(sub("^sqrt$", "other_sqrt", names(.)))
# var1 var2 other other_sqrt
# 1 1 4 9 3
# 2 2 5 9 3
# Example 2
df2 <- data.frame(var1 = 1:2, var2 = 4:5, other1 = 9, other2 = 16)
df2 %>%
mutate_at(vars(contains("other")), funs("sqrt" = sqrt(.))) %>%
setNames(sub("^sqrt$", "other_sqrt", names(.)))
# var1 var2 other1 other2 other1_sqrt other2_sqrt
# 1 1 4 9 16 3 4
# 2 2 5 9 16 3 4
Или мы можем разработать функцию для проверки, сколько столбцов содержат строку other
перед манипулированием фреймом данных.
mutate_sqrt <- function(df, string){
string_col <- grep(string, names(df), value = TRUE)
df2 <- df %>% mutate_at(vars(contains(string)), funs("sqrt" = sqrt(.)))
if (length(string_col) == 1){
df2 <- df2 %>% setNames(sub("^sqrt$", paste(string_col, "sqrt", sep = "_"), names(.)))
}
return(df2)
}
mutate_sqrt(df, "other")
# var1 var2 other other_sqrt
# 1 1 4 9 3
# 2 2 5 9 3
mutate_sqrt(df2, "other")
# var1 var2 other1 other2 other1_sqrt other2_sqrt
# 1 1 4 9 16 3 4
# 2 2 5 9 16 3 4
Я только что нашел (не очень чистый) способ сделать это; Я добавляю дополнительную фиктивную переменную к набору данных с именем, которое гарантирует, что он будет выбран, и что мы не попадем в случай с 1 переменной, и после вычисления я удалю 2 манекена, например так:
df %>% mutate(other_fake=NA) %>%
mutate_at(vars(contains("other")), .funs=funs('sqrt'=sqrt)) %>%
select(-contains("other_fake"))
#### var1 var2 other other_sqrt
#### 1 1 4 9 3
#### 2 2 5 9 3