使用 dplyr 和 purrr 重复改变变量
Repeatedly mutate variable using dplyr and purrr
我是自学 R 的,这是我的第一个 Whosebug 问题。如果这是一个明显的问题,我深表歉意;请善待。
我的问题的简短版本
我编写了一个自定义函数来计算变量年同比的百分比变化。我想使用 purrr
的 map_at
函数将我的自定义函数应用于变量名向量。我的自定义函数在应用于单个变量时有效,但在我使用 map_a
链接它时失败
我的自定义函数
calculate_delta <- function(df, col) {
#generate variable name
newcolname = paste("d", col, sep="")
#get formula for first difference.
calculate_diff <- lazyeval::interp(~(a + lag(a))/a, a = as.name(col))
#pass formula to mutate, name new variable the columname generated above
df %>%
mutate_(.dots = setNames(list(calculate_diff), newcolname)) }
当我将此函数应用于 mtcars 数据集中的单个变量时,输出符合预期(尽管结果的含义显然是无意义的)。
calculate_delta(mtcars, "wt")
尝试使用 Purrr 将函数应用于字符向量
我想我在概念化 map_at 如何将参数传递给函数时遇到了问题。我可以在网上找到的所有示例片段都使用 map_at 和 is.character
等函数,不需要额外的参数。这是我尝试使用 purrr
应用该函数的尝试。
vars <- c("wt", "mpg")
mtcars %>% map_at(vars, calculate_delta)
这给了我这条错误信息
Error in paste("d", col, sep = "") :
argument "col" is missing, with no default
我认为这是因为 map_at 将 vars
作为 df
传递,而不传递 col
的参数。为了解决这个问题,我尝试了以下方法:
vars <- c("wt", "mpg")
mtcars %>% map_at(vars, calculate_delta, df = .)
这给我带来了这个错误:
Error: unrecognised index type
我试过很多不同的版本,包括从 calculate_delta
函数中删除 df
参数,但我没有成功。
其他可能的解决方案
1) 使用 sapply
而不是 purrr
的版本。我试过以这种方式解决问题并且遇到了类似的麻烦。如果可能的话,我的目标是想出一种使用 purrr 来做到这一点的方法。根据我对 purrr
的理解,这似乎是一个典型的用例。
2) 我显然可以想到如何使用 for 循环来实现它,但出于类似的原因,我正在尽可能避免这种情况。
很明显我在想这个问题。请帮忙!
编辑 1
澄清一下,我很好奇是否有一种重复转换变量的方法可以完成两件事。
1) 在原始 tbl_df
中生成新变量,而不替换替换正在变异的列(就像使用 dplyr
的 mutate_at
时的情况)。
2) 自动生成新的变量标签。
3) 如果可能,通过使用 map_at
.
应用单个函数来完成我所描述的内容
这可能是不可能的,但我觉得应该有一种优雅的方式来完成我所描述的内容。
尝试简化流程:
delta <- function(x) (x + dplyr::lag(x)) /x
cols <- c("wt", "mpg")
#This
library(dplyr)
mtcars %>% mutate_at(cols, delta)
#Or
library(purrr)
mtcars %>% map_at(cols, delta)
#If necessary, in a function
f <- function(df, cols) {
df %>% mutate_at(cols, delta)
}
f(iris, c("Sepal.Width", "Petal.Length"))
f(mtcars, c("wt", "mpg"))
编辑
如果您想在之后嵌入新名称,我们可以编写自定义管道就绪函数:
Rename <- function(object, old, new) {
names(object)[names(object) %in% old] <- new
object
}
mtcars %>%
mutate_at(cols, delta) %>%
Rename(cols, paste0("lagged",cols))
如果要重命名生成的滞后变量:
mtcars %>% mutate_at(cols, funs(lagged = delta))
我是自学 R 的,这是我的第一个 Whosebug 问题。如果这是一个明显的问题,我深表歉意;请善待。
我的问题的简短版本
我编写了一个自定义函数来计算变量年同比的百分比变化。我想使用 purrr
的 map_at
函数将我的自定义函数应用于变量名向量。我的自定义函数在应用于单个变量时有效,但在我使用 map_a
我的自定义函数
calculate_delta <- function(df, col) {
#generate variable name
newcolname = paste("d", col, sep="")
#get formula for first difference.
calculate_diff <- lazyeval::interp(~(a + lag(a))/a, a = as.name(col))
#pass formula to mutate, name new variable the columname generated above
df %>%
mutate_(.dots = setNames(list(calculate_diff), newcolname)) }
当我将此函数应用于 mtcars 数据集中的单个变量时,输出符合预期(尽管结果的含义显然是无意义的)。
calculate_delta(mtcars, "wt")
尝试使用 Purrr 将函数应用于字符向量
我想我在概念化 map_at 如何将参数传递给函数时遇到了问题。我可以在网上找到的所有示例片段都使用 map_at 和 is.character
等函数,不需要额外的参数。这是我尝试使用 purrr
应用该函数的尝试。
vars <- c("wt", "mpg")
mtcars %>% map_at(vars, calculate_delta)
这给了我这条错误信息
Error in paste("d", col, sep = "") : argument "col" is missing, with no default
我认为这是因为 map_at 将 vars
作为 df
传递,而不传递 col
的参数。为了解决这个问题,我尝试了以下方法:
vars <- c("wt", "mpg")
mtcars %>% map_at(vars, calculate_delta, df = .)
这给我带来了这个错误:
Error: unrecognised index type
我试过很多不同的版本,包括从 calculate_delta
函数中删除 df
参数,但我没有成功。
其他可能的解决方案
1) 使用 sapply
而不是 purrr
的版本。我试过以这种方式解决问题并且遇到了类似的麻烦。如果可能的话,我的目标是想出一种使用 purrr 来做到这一点的方法。根据我对 purrr
的理解,这似乎是一个典型的用例。
2) 我显然可以想到如何使用 for 循环来实现它,但出于类似的原因,我正在尽可能避免这种情况。
很明显我在想这个问题。请帮忙!
编辑 1
澄清一下,我很好奇是否有一种重复转换变量的方法可以完成两件事。
1) 在原始 tbl_df
中生成新变量,而不替换替换正在变异的列(就像使用 dplyr
的 mutate_at
时的情况)。
2) 自动生成新的变量标签。
3) 如果可能,通过使用 map_at
.
这可能是不可能的,但我觉得应该有一种优雅的方式来完成我所描述的内容。
尝试简化流程:
delta <- function(x) (x + dplyr::lag(x)) /x
cols <- c("wt", "mpg")
#This
library(dplyr)
mtcars %>% mutate_at(cols, delta)
#Or
library(purrr)
mtcars %>% map_at(cols, delta)
#If necessary, in a function
f <- function(df, cols) {
df %>% mutate_at(cols, delta)
}
f(iris, c("Sepal.Width", "Petal.Length"))
f(mtcars, c("wt", "mpg"))
编辑
如果您想在之后嵌入新名称,我们可以编写自定义管道就绪函数:
Rename <- function(object, old, new) {
names(object)[names(object) %in% old] <- new
object
}
mtcars %>%
mutate_at(cols, delta) %>%
Rename(cols, paste0("lagged",cols))
如果要重命名生成的滞后变量:
mtcars %>% mutate_at(cols, funs(lagged = delta))