使用mutate_each在sparklyr

时间:2017-12-13 22:20:28

标签: r apache-spark dplyr data-science sparklyr

我正在处理sparklyr中的群集问题。训练集中的许多变量是在不同的尺度上测量的,因此在数量级上不同。根据最佳实践,我试图扩展和居中数据。

有许多不同的公式可以做到这一点,最传统的是(X - μ)/σ,其中X是随机变量,μ=平均值,σ=标准差。我倾向于使用(X - x)/(x_max - x_min),其中X =随机变量,x =样本均值,x_max =最大值,x_min =最小值。

使用dplyr应用此转换后,我得到了一个奇怪的结果。考虑这个例子:

    #connect to spark
    library(sparklyr)
    library(SparkR)
    library(dplyr)
    sc = spark_connect(master = 'yarn-client',
                       spark_home = '/usr/hdp/current/spark-client',
                       app_name = 'sparklyr'
                       # config = list(
                       #   "sparklyr.shell.executor-memory" = "XG",
                       #   "sparklyr.shell.driver-memory"   = "XG",
                       #   "spark.driver.maxResultSize"     = "XG" # may need to transfer a lot of data into R 
    )

    sparkR.init()

#create a dataframe where variables in the dataset differ by an order of magnitude
mat <- as.data.frame(matrix(data = rnorm(200, mean=100,sd=10), nrow = 1000, ncol = 50))
mat1 <- as.data.frame(matrix(data = rnorm(200, mean=0,sd=1), nrow = 1000, ncol = 50))
colnames(mat1) <- paste('X',1:50,sep='')
mat.final <- cbind(mat,mat1)

#copy to Spark
dat.out <- sdf_copy_to(sc,mat.final,'dat',overwrite=TRUE)

#define centering and scaling function
scale.center <- function(x){
  (x-mean(x,na.rm=TRUE)) /(max(x,na.rm = TRUE)-min(x,na.rm = TRUE))
}

#scale data
dat.out1 <- 
  dat.out %>%
  mutate_each(funs(s=scale.center))

代码运行,但我有点奇怪:

str(dat.out1)

$ ops:List of 4
  ..$ name: chr "mutate"
  ..$ x   :List of 4
  .. ..$ name: chr "mutate"
  .. ..$ x   :List of 4
  .. .. ..$ name: chr "mutate"
  .. .. ..$ x   :List of 4
  .. .. .. ..$ name: chr "mutate"
  .. .. .. ..$ x   :List of 4
  .. .. .. .. ..$ name: chr "mutate"
  .. .. .. .. ..$ x   :List of 4
  .. .. .. .. .. ..$ name: chr "mutate"
  .. .. .. .. .. ..$ x   :List of 4
  .. .. .. .. .. .. ..$ name: chr "mutate"
  .. .. .. .. .. .. ..$ x   :List of 4
  .. .. .. .. .. .. .. ..$ name: chr "mutate"
  .. .. .. .. .. .. .. ..$ x   :List of 4
  .. .. .. .. .. .. .. .. ..$ name: chr "mutate"
  .. .. .. .. .. .. .. .. ..$ x   :List of 4
  .. .. .. .. .. .. .. .. .. ..$ name: chr "mutate"
  .. .. .. .. .. .. .. .. .. ..$ x   :List of 4
  .. .. .. .. .. .. .. .. .. .. ..$ name: chr "mutate"
  .. ..

以上只是运行str后输出的一部分。关于这里出了什么问题的想法。令我感到惊讶的是,没有用于居中和缩放的功能。

1 个答案:

答案 0 :(得分:3)

  

关于这里出了什么问题的想法。

它与Sparklyr: how to center a Spark table based on column?中描述的问题基本相同 - mutate中使用的聚合函数被扩展为全局(没有PARTITION BY子句)窗口函数,使得这种方法在实践中完全无用。

  

我很惊讶,没有用于居中和缩放的功能。

嗯,一般来说,Spark使用ML Transformers进行操作,其中一组已被移植到sparklyr。这些可以通过ft_前缀来区分。很遗憾,StandardScalerMinMaxScaler尚未移植。但是,实现自己的界面并不难。

如果你想要一个可以按原样处理数据的快速:

library(rlang)
library(glue)

# Compute all the stats at once
stats <- dat.out %>% summarise_all(funs(avg, min, max)) %>% collect()

# Separate stats into components
cols <- dat.out %>% colnames()
avgs <- stats %>% select(ends_with("avg")) %>% unlist
mins <- stats %>% select(ends_with("min")) %>% unlist
maxs <- stats %>% select(ends_with("max")) %>% unlist

# Create expressions
exprs <- glue("({cols} - {avgs}) / ({maxs} - {mins})") %>% 
  setNames(cols) %>%
  lapply(parse_quosure)

dat.out %>% mutate(!!! exprs)

积分再次转到Artem Sokolovdplyr 0.7 equivalent for deprecated mutate_)。

注意

请勿使用.sparklyr一起使用的功能。 dplyr将尝试将这些作为数据库函数匹配在&#34;前缀&#34;数据库失败或产生意外结果。