Я создаю функцию динамической перестановки для создания независимых параметров порядка. Вне функции я смог жестко подписать этот подход с помощью dplyr. Однако я хочу обобщить его так, чтобы я мог использовать одну и ту же функцию для перестановки 3 факторов или 6 факторов без ввода всех повторяющихся вызовов. Однако я не понял, как заставить его работать.Как создать динамический номер и имя мутате вызовов в dplyr?
Вот простой кадр данных df
всех перестановки 3 переменных:
#> dput(df)
structure(list(var1 = structure(c(1L, 1L, 2L, 2L, 3L, 3L), .Label = c("a",
"b", "c"), class = "factor"), var2 = structure(c(2L, 3L, 1L,
3L, 1L, 2L), .Label = c("a", "b", "c"), class = "factor"), var3 = structure(c(3L,
2L, 3L, 1L, 2L, 1L), .Label = c("a", "b", "c"), class = "factor"),
X1 = c(0.5, 0.5, 0.8, 0.8, 0.3, 0.3), X2 = c(0.8, 0.3, 0.5,
0.3, 0.5, 0.8), X3 = c(0.3, 0.8, 0.3, 0.5, 0.8, 0.5)), .Names = c("var1",
"var2", "var3", "X1", "X2", "X3"), row.names = c(NA, -6L), class = "data.frame")
Моя цель состоит в том, чтобы добраться до среднего самостоятельного значения порядка каждый переменный. Чтобы добраться туда, мне нужно создать две промежуточные переменные: одну умножить m1, m2, m3, m4
и одну вычесть s1, s2, s3, s4
. Переменные m1
и s1
являются специальными, m1 = X1
и s1 = X1-1
. Тем не менее, другие должны обратиться к предыдущему: m2 = X2*X1
и s2 = m2-m1
.
Я попытался объединить идеи из этого вопроса SO: R - dplyr - mutate - use dynamic variable names с lazyeval interp, чтобы я мог динамически ссылаться на другие переменные, а также динамически назвать мутированные столбцы. Тем не менее, он оставил только последний отправленный, и переименование не сработало, поэтому я получил один дополнительный столбец, названный, например, X2*X3
, что хорошо в этом примере с 3. Когда у меня было 5, он дал один дополнительная колонка X4*X5
.
for(n in 2:n_params) {
varname <- paste("m", n, sep=".")
df <- mutate_(df, .dots = setNames(interp(~one*two, one=as.name(paste0("X",n-1)),
two=as.name(paste0("X",n))),varname))
df
}
Так как я не могу понять, почему это не работает, я создал серию, если заявления, вычислить m
с и s
с.
xx <- data.frame(df) %>%
mutate(m1 = X1,
s1 = X1 - 1)
if(n_params >= 2) {
xx <- data.frame(xx) %>%
mutate(m2 = m1 * X2,
s2 = m2 - m1)
}
if(n_params >= 3) {
xx <- data.frame(xx) %>%
mutate(m3 = m2 * X3,
s3 = m3 - m2)
}
if(n_params >= 4) {
xx <- data.frame(xx) %>%
mutate(m4 = m3 * X4,
s4 = m4 - m3)
}
if(n_params >= 5) {
xx <- data.frame(xx) %>%
mutate(m5 = m4 * X5,
s5 = m5 - m4)
}
if(n_params >= 6) {
xx <- data.frame(xx) %>%
mutate(m6 = m5 * X6,
s6 = m6 - m5)
}
Похоже, что я должен быть в состоянии написать функцию, которая создает это,
В псевдокоде:
function(n_params) {
function(x) {
new_df <- df %>%
mutate(m1 = X1,
s1 = X1 - 1)
for(i in 2:n_params){
new_df <- append(call to new_df,
mutate(mi = Xi*Xi-1,
si = mi-mi-1)
}
}
}
Однако, я не могу понять, как совместить lazyeval interp
и setNames чтобы позволить ссылаться на предыдущее мутированное значение.
Я мог бы просто оставить его, если функции, но я хотел бы сделать это более компактным, если это возможно.
Конечный конечный результат представляет собой среднее значение s по всем перестановкам для каждой начальной переменной. Я делаю это в отдельной функции.
Я думаю, что у меня может быть вопрос о версии. Если я попробую это, xx1 создаст m2 и s2, но когда он попытается создать m3, он не сможет найти m2. error 'Ошибка: object 'm2' not found' Я запускаю: R версии 3.2.2 (2015-08-14) с lazyeval_0.1.10 dplyr_0.4.3; ошибка относится к Rcpp, и это Rcpp_0.12.1. 'stop (struct (list (message =" object 'm2' not found ", call = NULL, cppstack = NULL).Names = c ("message", "call", "cppstack" ), class = c ("Rcpp :: eval_error", "C++ Error", "error", "condition" ))) ' – jessi
My Версия Rcpp равна 0.12.2, но в противном случае мы сопоставим. – Gregor
Моя ошибка, у меня была 'xx1 = xx%>%' - это никогда не сработает. Спасибо за решение этого. * мой большой вопрос * Интересно, почему 'list' работает и сохраняет значения и имена, но' interp' не сделал. – jessi