【发布时间】:2019-11-01 19:57:36
【问题描述】:
我有一个函数,我想只迭代数据集中的某些行,然后将结果保存在数据集中的变量中。
例如说我有这个设置:
library(tidyverse)
add_one <- function(vector, x_id){
return(vector[x_id] + 1)
}
test <- data.frame(x = c(1,2,3,4), y = c(1,2,3,4), run_on = c(TRUE,FALSE,TRUE,FALSE))
test
所以测试数据框看起来像:
> x y run_on
>1 1 1 TRUE
>2 2 2 FALSE
>3 3 3 TRUE
>4 4 4 FALSE
所以我想要做的是遍历数据框并将 y 列设置为将函数 add_one() 应用于 x 列的结果,仅适用于 run_on 为 TRUE 的行。我希望最终结果如下所示:
> x y run_on
>1 1 2 TRUE
>2 2 2 FALSE
>3 3 4 TRUE
>4 4 4 FALSE
我已经能够使用 apply() 在所有行上迭代该函数。比如:
test$y <- apply(test,1,add_one,x_id = 1)
test
> x y run_on
>1 1 2 TRUE
>2 2 3 FALSE
>3 3 4 TRUE
>4 4 5 FALSE
但这也将函数应用于第 2 行和第 4 行,这是我不想要的。我怀疑可能有某种方法可以使用 ::purrr 中的 map() 函数版本来做到这一点,这就是我将这篇文章标记为这样的原因。
实际上,我正在使用这种过程多次重复迭代大型数据集,因此我需要它自动且干净地完成。任何帮助或建议将不胜感激。
更新
我设法找到了解决方案。这里提供的一些解决方案在我的玩具示例中确实有效,但没有扩展到我实际使用的更复杂的功能。最终起作用的是类似于 tmfmnk 建议的东西。我只是将原始函数包装在另一个函数中,该函数包含一个 if 语句以确定是否应用原始函数。因此,为了扩展我的玩具示例,我的解决方案如下所示:
add_one_if <- function(vector, x_id, y_id, run_on_id){
if(vector[run_on_id]){
return(add_one(vector,x_id))}
else{
return(vector[x_id])
}
}
test$y <- apply(test, 1, add_one_if, x_id = 1, y_id = 2, run_on_id = 3)
这似乎有点令人费解,但它对我有用,并且以我需要的方式可重复且可靠。
【问题讨论】:
-
with(test, y + run_on);) -
如果 jcr 真的只是在列中添加一个,这是一个聪明的解决方案。但是,听起来这只是一个示例,在这种情况下,这不会推广到其他功能。