在闪耀的tbl上计算qchisq

时间:2018-05-16 10:29:54

标签: r apache-spark apache-spark-sql sparklyr chi-squared

我需要在sparklyr数据帧的列上使用qchisq函数。

问题是似乎qchisq函数没有在Spark中实现。如果我正在正确读取下面的错误消息,那么sparklyr尝试执行一个名为“QCHISQ”的函数,但这在Hive SQL和Spark中都不存在。

一般来说,有没有办法运行没有在Hive或Spark中实现的任意函数,使用sparklyr?我知道spark_apply,但还没弄明白如何配置它。

public override void ViewDidLoad() {
       base.ViewDidLoad();

       var frame = CoreGraphics.CGRect.Empty;
       frame.Height = 1;
       myTableview.TableHeaderView = new UIView(frame);
       myTableview.TableFooterView = new UIView(frame);
}

2 个答案:

答案 0 :(得分:1)

如您所述,您可以使用spark_apply

mydf_tbl %>% 
  spark_apply(function(df) 
    dplyr::mutate(df, se = sqrt(beta^2/qchisq(pval, df = 12))))

# # Source:   table<sparklyr_tmp_14bd5feacf5> [?? x 3]
# # Database: spark_connection
#      beta   pval     X3
#     <dbl>  <dbl>  <dbl>
#  1  1.66  0.0763 0.686 
#  2  0.153 0.0872 0.0623
#  3  2.96  0.0485 1.30  
#  4  4.86  0.0349 2.22  
#  5 -1.82  0.0712 0.760 
#  6  2.34  0.0295 1.10  
#  7  3.54  0.0297 1.65  
#  8  4.57  0.0784 1.88  
#  9  4.94  0.0394 2.23  
# 10 -0.610 0.0906 0.246 
# # ... with more rows

但公平警告 - 这是令人尴尬的缓慢。不幸的是,除了编写自己的Scala / Java扩展之外,你还没有其他选择。

答案 1 :(得分:0)

最后,我使用了一个可怕的黑客,这种情况下工作正常。

另一种解决方案是编写用户定义函数(UDF),但闪耀者还没有支持它:https://github.com/rstudio/sparklyr/issues/1052

这是我使用的黑客。简而言之,我预先计算了qchisq表,将其作为sparklyr对象上传,然后加入。如果我将其与在本地数据帧上计算的结果进行比较,我会得到r = 0.99999990902236146617的相关性。

#' @param n: number of significant digits to use
> check_precomputed_strategy = function(n) { 
    chisq = data.frame(pval=seq(0, 1, 1/(10**(n)))) %>%
            mutate(qval=qchisq(pval, df=1, lower.tail = FALSE)) %>%
            mutate(pval_s = as.character(round(as.integer(pval*10**n),0)))
    chisq %>% head %>% print
    chisq_tbl = copy_to(con, chisq, overwrite=T)

    mydf = data.frame(beta=runif(100, -5, 5), pval = runif(100, 0.001, 0.1)) %>%
        mutate(se1 = sqrt(beta^2/qchisq(pval, df=1, lower.tail = FALSE)))
    mydf_tbl = copy_to(con, mydf)

    mydf_tbl.up  = mydf_tbl %>%
            mutate(pval_s=as.character(round(as.integer(pval*10**n),0)))  %>%
            left_join(chisq_tbl, by="pval_s") %>%
            mutate(se=sqrt(beta^2 / qval)) %>%
            collect %>%
            filter(!duplicated(beta))

    mydf_tbl.up %>% head %>% print
    mydf_tbl.up %>% filter(complete.cases(.)) %>% nrow %>% print
    mydf_tbl.up %>% filter(complete.cases(.)) %>% select(se, se1) %>% cor

}
> check_precomputed_strategy(4)
                       pval                  qval pval_s
1 0.00000000000000000000000                   Inf      0
2 0.00010000000000000000479 15.136705226623396570      1
3 0.00020000000000000000958 13.831083619091122827      2
4 0.00030000000000000002793 13.070394140069462097      3
5 0.00040000000000000001917 12.532193305401813532      4
6 0.00050000000000000001041 12.115665146397173402      5
# A tibble: 6 x 8
    beta  pval.x   se1 myvar pval_s  pval.y  qval    se
   <dbl>   <dbl> <dbl> <dbl> <chr>    <dbl> <dbl> <dbl>
1  3.42  0.0913  2.03     1. 912    0.0912   2.85 2.03
2 -1.72  0.0629  0.927    1. 628    0.0628   3.46 0.927
3  0.515 0.0335  0.242    1. 335    0.0335   4.52 0.242
4 -3.12  0.0717  1.73     1. 716    0.0716   3.25 1.73
5 -2.12  0.0253  0.947    1. 253    0.0253   5.00 0.946
6  1.36  0.00640 0.498    1. 63     0.00630  7.46 0.497
[1] 100
                        se                    se1
se  1.00000000000000000000 0.99999990902236146617
se1 0.99999990902236146617 1.00000000000000000000