当前位置: 首页 > 知识库问答 >
问题:

将变量名列表传递给带有mutate的自定义函数

夏星阑
2023-03-14

我正在尝试使用tidyverse对每一行执行一个函数并创建一个考虑多列的新列,我最初使用的是rowwise(),但速度非常慢。我希望我的自定义函数中的列列表是一个变量,但除非显式地列出变量名,否则无法使其工作。例如,这是可行的:

low_risk_codes <- c(0,1,10)
vars <- c("V1", "V2")
m <- matrix(1:9, ncol=3)
classify_low_risk_drug <- function(...){
  t <- cbind(...)
  return(apply(t, 1, function(x) ifelse(any(x %in% low_risk_codes), 1, 0)))
}

as.data.frame(m) %>%
  mutate(val4 = classify_low_risk_drug(V1, V2))

但如果我希望它使用列输入作为vars进行计算:

as.data.frame(m) %>% 
  mutate(val4 = classify_low_risk_drug(vars))

共有1个答案

戚鸿
2023-03-14

这听起来像它会做你想要的,但我需要限定它(很多)。首先,请注意,我仍然把我的思想缠绕在R的NSE上,但我发现这个小插曲很有帮助。

与解决方案相关,我试图通过避免rowwise()apply()来加快函数的速度。使用rapply()/rowsums()应该会更快,但我没有对其进行基准测试。对于非常大的数据,它可能会遇到问题,因为rowsums()会将数据帧转换为矩阵,但这可能不是问题。理论上,您还应该能够使用select helpers/未加引号的变量名/列位置(如果您敢的话)。

另外,我发现您需要提供dataframe作为第一个参数(即.)有点奇怪,但可能有一种方法可以解决这一问题。我当然愿意接受任何想要编辑这篇文章/使用这篇文章作为他们解决方案的基础的人。希望这能帮助你走向正确的方向!

classify_low_risk_drug <- function(.data, vars, codes, na.rm = FALSE){

  df <- rapply(.data, function(x) x %in% codes, how = "replace")
  as.integer(rowSums(select(df, !!enquo(vars)), na.rm = na.rm) > 0)

  }

as.data.frame(m) %>%
  mutate(val4 = classify_low_risk_drug(., vars = vars, codes = c(0, 1, 10)))
  V1 V2 V3 val4
1  1  4  7    1
2  2  5  8    0
3  3  6  9    0

编辑:通过避免矩阵转换/使用lapply()pmax(),您可以稍微提高速度:

classify_low_risk_drug2 <- function(.data, vars, codes, na.rm = FALSE){

  as.integer(do.call(pmax, lapply(select(.data, !!enquo(vars)), `%in%`, codes)))

}
 类似资料:
  • 我定义了一个变量: 在

  • 问题内容: 我有一个包含13个不同列名的数据框,我将这些标题分为两个列表。我现在想对每个列表执行不同的操作。 是否可以将列名作为变量传递给pandas?目前,我的代码可以在列表中循环,但是我在尝试将列名传递给函数时遇到了麻烦 码 问题答案: 我认为您可以使用创建自 : 也许更好,因为是,这是由创建:

  • 问题内容: 如果我有 我如何在内部找出现在由表示的变量称为? 问题答案: 这是不可能的。即使是按引用传递也不会帮助您。您必须将名称作为第二个参数传递。 但是,您肯定要问的 不是 解决问题的好方法。

  • 问题内容: 我想按值将列表传递给函数。默认情况下,列表和其他复杂对象通过引用传递给函数。这是一些目标: 可以写得短些吗?换句话说,我不想更改 ad 。 问题答案: 您可以使用,但是对于包含列表(或其他可变对象)的列表,您应该使用: 等价于或,并返回列表的浅表副本。 何时使用:

  • 问题内容: 我感觉这不可能,但是我想确定已传递给javascript函数的变量的原始变量名。我不知道该如何更好地解释它,所以看看这个例子是否有意义。 这是我正在使用的jquery插件,我希望能够显示传递给“调试”函数的变量的名称。 问题答案: 没错,以任何理智的方式这都是不可能的,因为只有值才传递到函数中。