在dplyr中的汇总函数中使用if语句调用自定义函数

时间:2014-08-21 03:29:37

标签: r dplyr

我需要调用自定义函数来进行一些计算。在此函数中,有一个if语句用于检查输入值。但是我的代码不会返回我期望的值。

创建了测试data.frame

library(dplyr)
df <- expand.grid(x = 2:4, y = 2:4, z = 2:4)
df$value <- df$x
df <- df%>% tbl_df %>% group_by(x, y)

test_fun1只返回所有值的总和

test_fun1 <- function(value)
{
    return(sum(value))
}
df %>% summarize(t  = test_fun1(value))

test_fun1将结果返回为我的预期

Source: local data frame [4 x 3]
Groups: x

  x y t
1 1 1 2
2 1 2 2
3 2 1 4
4 2 2 4

然后我添加一个if语句来检查所有值是否相等。

test_fun2 <- function(value)
{
    if (all(value == 2))
    {
        return (NA)
    }
    return(sum(value))
}
df  %>% summarize(t  = test_fun2(value))

但是test_fun2对于值大于2

返回TRUE
Source: local data frame [9 x 3]
Groups: x

  x y    t
1 2 2   NA
2 2 3   NA
3 2 4   NA
4 3 2 TRUE
5 3 3 TRUE
6 3 4 TRUE
7 4 2 TRUE
8 4 3 TRUE
9 4 4 TRUE

对于其他值,test_fun3的其他值的结果与预期一致。

test_fun3 <- function(value)
{
    if (all(value != 3))
    {
        return(sum(value))
    }
    return (NA)

}
df  %>% summarize(t  = test_fun3(value))

我可以得到4或5的类似结果

Source: local data frame [9 x 3]
Groups: x

  x y  t
1 2 2  6
2 2 3  6
3 2 4  6
4 3 2 NA
5 3 3 NA
6 3 4 NA
7 4 2 12
8 4 3 12
9 4 4 12

在我的真实数据中,我对非NA测试感到错误,但是在这里无法创建重现示例。

有关此问题的任何想法?感谢您的任何建议。

sessionInfo()
R version 3.1.0 (2014-04-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)

locale:
[1] LC_COLLATE=English_Australia.1252  LC_CTYPE=English_Australia.1252   
[3] LC_MONETARY=English_Australia.1252 LC_NUMERIC=C                      
[5] LC_TIME=English_Australia.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] dplyr_0.2

loaded via a namespace (and not attached):
[1] assertthat_0.1.0.99 magrittr_1.0.1      parallel_3.1.0     
[4] Rcpp_0.11.1         tools_3.1.0        

1 个答案:

答案 0 :(得分:9)

问题显然是mutate尝试从第一次分配中确定列的类,并将此类应用于所有其他组。 NA的课程(不幸的是)logical。有关详细信息,请查看https://github.com/hadley/dplyr/issues/299

我建议你通过分配一个铸造的NA来解决这个问题。另请参阅? NA

test_fun2 <- function(value) {
  if (all(value == 2)) {
    return (NA_integer_)
  }
  return(sum(value))
}

df  %>% summarize(t  = test_fun2(value))

Source: local data frame [9 x 3]
Groups: x

  x y  t
1 2 2 NA
2 2 3 NA
3 2 4 NA
4 3 2  9
5 3 3  9
6 3 4  9
7 4 2 12
8 4 3 12
9 4 4 12