如何将函数映射为仅应用于数据框中的某些行?

时间:2019-11-01 19:57:36

标签: r purrr

我有一个函数,希望仅对数据集的某些行进行迭代,然后将结果保存到数据集中的变量中。

例如,说我已经设置好了:

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)

这似乎有些令人费解,但是它对我有用,并且可以按照我的要求进行再现和可靠。

3 个答案:

答案 0 :(得分:2)

您的真实情况可能比此情况所允许的更为复杂,但为什么不仅使用ifelse?

test$y <- ifelse(test$run_on,add_one(test,x),y)

甚至:

test$y[test$run_on]<-add_one(test[run_on,],x)

答案 1 :(得分:2)

您也可以这样做:

"allow_origins": ["http*"]

答案 2 :(得分:1)

在将相同的功能应用于多个列之前,无需使用purrr。由于您只想修改一个列,但是可以根据条件使用mutate() + case_when()

mutate(test, y = case_when(run_on ~ add_one(y),
                           !run_on ~ y))
#>   x y run_on
#> 1 1 2   TRUE
#> 2 2 2  FALSE
#> 3 3 4   TRUE
#> 4 4 4  FALSE