Skip to content

Commit b9455d1

Browse files
adrian555shivaram
authored andcommitted
[SPARK-11260][SPARKR] with() function support
Author: adrian555 <[email protected]> Author: Adrian Zhuang <[email protected]> Closes #9443 from adrian555/with.
1 parent 8a5314e commit b9455d1

File tree

5 files changed

+51
-6
lines changed

5 files changed

+51
-6
lines changed

R/pkg/NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ exportMethods("arrange",
8383
"unique",
8484
"unpersist",
8585
"where",
86+
"with",
8687
"withColumn",
8788
"withColumnRenamed",
8889
"write.df")

R/pkg/R/DataFrame.R

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2126,11 +2126,29 @@ setMethod("as.data.frame",
21262126
setMethod("attach",
21272127
signature(what = "DataFrame"),
21282128
function(what, pos = 2, name = deparse(substitute(what)), warn.conflicts = TRUE) {
2129-
cols <- columns(what)
2130-
stopifnot(length(cols) > 0)
2131-
newEnv <- new.env()
2132-
for (i in 1:length(cols)) {
2133-
assign(x = cols[i], value = what[, cols[i]], envir = newEnv)
2134-
}
2129+
newEnv <- assignNewEnv(what)
21352130
attach(newEnv, pos = pos, name = name, warn.conflicts = warn.conflicts)
21362131
})
2132+
2133+
#' Evaluate a R expression in an environment constructed from a DataFrame
2134+
#' with() allows access to columns of a DataFrame by simply referring to
2135+
#' their name. It appends every column of a DataFrame into a new
2136+
#' environment. Then, the given expression is evaluated in this new
2137+
#' environment.
2138+
#'
2139+
#' @rdname with
2140+
#' @title Evaluate a R expression in an environment constructed from a DataFrame
2141+
#' @param data (DataFrame) DataFrame to use for constructing an environment.
2142+
#' @param expr (expression) Expression to evaluate.
2143+
#' @param ... arguments to be passed to future methods.
2144+
#' @examples
2145+
#' \dontrun{
2146+
#' with(irisDf, nrow(Sepal_Width))
2147+
#' }
2148+
#' @seealso \link{attach}
2149+
setMethod("with",
2150+
signature(data = "DataFrame"),
2151+
function(data, expr, ...) {
2152+
newEnv <- assignNewEnv(data)
2153+
eval(substitute(expr), envir = newEnv, enclos = newEnv)
2154+
})

R/pkg/R/generics.R

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,3 +1043,7 @@ setGeneric("as.data.frame")
10431043
#' @rdname attach
10441044
#' @export
10451045
setGeneric("attach")
1046+
1047+
#' @rdname with
1048+
#' @export
1049+
setGeneric("with")

R/pkg/R/utils.R

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,3 +623,16 @@ convertNamedListToEnv <- function(namedList) {
623623
}
624624
env
625625
}
626+
627+
# Assign a new environment for attach() and with() methods
628+
assignNewEnv <- function(data) {
629+
stopifnot(class(data) == "DataFrame")
630+
cols <- columns(data)
631+
stopifnot(length(cols) > 0)
632+
633+
env <- new.env()
634+
for (i in 1:length(cols)) {
635+
assign(x = cols[i], value = data[, cols[i]], envir = env)
636+
}
637+
env
638+
}

R/pkg/inst/tests/test_sparkSQL.R

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,6 +1494,15 @@ test_that("attach() on a DataFrame", {
14941494
expect_error(age)
14951495
})
14961496

1497+
test_that("with() on a DataFrame", {
1498+
df <- createDataFrame(sqlContext, iris)
1499+
expect_error(Sepal_Length)
1500+
sum1 <- with(df, list(summary(Sepal_Length), summary(Sepal_Width)))
1501+
expect_equal(collect(sum1[[1]])[1, "Sepal_Length"], "150")
1502+
sum2 <- with(df, distinct(Sepal_Length))
1503+
expect_equal(nrow(sum2), 35)
1504+
})
1505+
14971506
unlink(parquetPath)
14981507
unlink(jsonPath)
14991508
unlink(jsonPathNa)

0 commit comments

Comments
 (0)