我正在尝试使用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))
这听起来像它会做你想要的,但我需要限定它(很多)。首先,请注意,我仍然把我的思想缠绕在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插件,我希望能够显示传递给“调试”函数的变量的名称。 问题答案: 没错,以任何理智的方式这都是不可能的,因为只有值才传递到函数中。