使用dplyr和purrr重复变量变量

Sea*_*ams 5 r dplyr purrr non-standard-evaluation

我在R中自学成才,这是我的第一个StackOverflow问题.如果这是一个明显的问题,我道歉; 请善待.

我的问题的简短版本
我编写了一个自定义函数来计算变量年份的变化百分比.我想使用purrrmap_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)) }
Run Code Online (Sandbox Code Playgroud)

当我将此函数应用于mtcars数据集中的单个变量时,输出与预期一致(尽管显然结果的含义是非敏感的).

calculate_delta(mtcars, "wt")
Run Code Online (Sandbox Code Playgroud)

尝试使用Purrr将函数应用于字符向量

我认为我无法概念化map_at如何将参数传递给函数.我可以在网上找到的所有示例片段都使用map_at和类似的函数is.character,这些函数不需要额外的参数.以下是我尝试使用该功能的尝试purrr.

vars <- c("wt", "mpg")
mtcars %>% map_at(vars, calculate_delta)
Run Code Online (Sandbox Code Playgroud)

这给了我这个错误信息

粘贴错误("d",col,sep =""):缺少参数"col",没有默认值

我想这是因为map_at被路过varsdf,而不是传递参数的col.为了解决这个问题,我尝试了以下方法:

vars <- c("wt", "mpg") 
mtcars %>% map_at(vars, calculate_delta, df = .)
Run Code Online (Sandbox Code Playgroud)

这引发了我这个错误:

Error: unrecognised index type
Run Code Online (Sandbox Code Playgroud)

我和一些不同的版本一起玩,包括dfcalculate_delta函数中删除参数,但我没有运气.

其他潜在解决方案

1)这个使用的版本sapply,而不是purrr.我试过这样解决问题并遇到类似麻烦.我的目标是找出一种方法来使用purrr,如果可能的话.根据我的理解purrr,这似乎是一个典型的用例.

2)我显然可以想到如何使用for循环来实现它,但是我试图避免这种情况,如果可能的话.

显然我在考虑这个错误.请帮忙!

编辑1

为了澄清,我很好奇是否有一种方法可以反复转换完成两件事的变量.

1)生成的原始内新的变量tbl_df,而无需更换更换被突变的列(如使用时的情况dplyrmutate_at).

2)自动生成新的变量标签.

3)如果可能,通过使用单个函数完成我所描述的内容map_at.

这可能是不可能的,但我觉得应该有一种优雅的方式来完成我所描述的内容.

Pie*_*une 10

尝试简化流程:

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"))
Run Code Online (Sandbox Code Playgroud)

编辑

如果您想在之后嵌入新名称,我们可以编写自定义管道就绪函数:

Rename <- function(object, old, new) {
  names(object)[names(object) %in% old] <- new
  object
}

mtcars %>% 
  mutate_at(cols, delta) %>% 
  Rename(cols, paste0("lagged",cols))
Run Code Online (Sandbox Code Playgroud)

如果要重命名结果滞后变量:

mtcars %>% mutate_at(cols, funs(lagged = delta))
Run Code Online (Sandbox Code Playgroud)

  • @SeanWilliams`mutate_at`如果你要添加一个后缀名,就不必替换列:`mtcars%>%mutate_at(cols,funs(lagged = delta))` (2认同)