The following is a minimal reproducible example. The issue is what gets sent to a function when using by and get together. The third example below which runs source("DT_Test.R") on OSX/R 3.3/Data table 1.9.7 is where the inconsistency comes.
Test Script: DT_Test.R
#############################################################
###
### Test of data.table bug for R 3.3 on Mac but not on Linux
###
#############################################################
### Load data.table package
require(data.table)
### Create data data
tmp_dt <- data.table(
CONTENT_AREA="READING",
YEAR="2016",
GRADE="3",
SCALE_SCORE=rnorm(50)
)
### Test function
test_function <- function(content_area, year, grade, scale_score) {
print(paste("Length of content_area vector:", length(content_area)))
print(paste("Length of year vector:", length(year)))
print(paste("Length of grade vector:", length(grade)))
print(paste("Length of scale_score vector:", length(scale_score)))
}
### Test #1
cat("\n\nTest #1: With variable name\n")
tmp_dt[, test_function(CONTENT_AREA, YEAR, GRADE, SCALE_SCORE), by=list(CONTENT_AREA, YEAR, GRADE)]
### Test #2 (with get())
scale.score.name <- "SCALE_SCORE"
cat("\n\nTest #2: With get()\n")
tmp_dt[, test_function(CONTENT_AREA, YEAR, GRADE, get(scale.score.name)), by=list(CONTENT_AREA, YEAR, GRADE)]
### Test #3 (with eval(parse(text)))
scale.score.name <- "SCALE_SCORE"
cat("\n\nTest #3: With eval(parse(text()))\n")
tmp_dt[, test_function(CONTENT_AREA, YEAR, GRADE, eval(parse(text=scale.score.name))), by=list(CONTENT_AREA, YEAR, GRADE)]
1: Results for Linux R 3.3 with data.table 1.9.7 (NO PROBLEMS, all vectors passed of length 1 except for SCALE_SCORE)
> source("DT_Test.R")
Test #1: With variable name
[1] "Length of content_area vector: 1"
[1] "Length of year vector: 1"
[1] "Length of grade vector: 1"
[1] "Length of scale_score vector: 50"
Test #2: With get()
[1] "Length of content_area vector: 1"
[1] "Length of year vector: 1"
[1] "Length of grade vector: 1"
[1] "Length of scale_score vector: 50"
Test #3: With eval(parse(text()))
[1] "Length of content_area vector: 1"
[1] "Length of year vector: 1"
[1] "Length of grade vector: 1"
[1] "Length of scale_score vector: 50"
2: Results for OSX R 3.3 with data.table 1.9.6 (NO PROBLEMS, all vectors passed of length 1 except for SCALE_SCORE)
> source("DT_Test.R")
Test #1: With variable name
[1] "Length of content_area vector: 1"
[1] "Length of year vector: 1"
[1] "Length of grade vector: 1"
[1] "Length of scale_score vector: 50"
Test #2: With get()
[1] "Length of content_area vector: 1"
[1] "Length of year vector: 1"
[1] "Length of grade vector: 1"
[1] "Length of scale_score vector: 50"
Test #3: With eval(parse(text()))
[1] "Length of content_area vector: 1"
[1] "Length of year vector: 1"
[1] "Length of grade vector: 1"
[1] "Length of scale_score vector: 50"
3: Results for OSX R 3.3 with data.table 1.9.7 (PROBLEMS with Test #2 below, all vectors passed of length 50)
> source("DT_Test.R")
Test #1: With variable name
[1] "Length of content_area vector: 1"
[1] "Length of year vector: 1"
[1] "Length of grade vector: 1"
[1] "Length of scale_score vector: 50"
Test #2: With get()
[1] "Length of content_area vector: 50"
[1] "Length of year vector: 50"
[1] "Length of grade vector: 50"
[1] "Length of scale_score vector: 50"
Test #3: With eval(parse(text()))
[1] "Length of content_area vector: 1"
[1] "Length of year vector: 1"
[1] "Length of grade vector: 1"
[1] "Length of scale_score vector: 50"
The following is a minimal reproducible example. The issue is what gets sent to a function when using
byandgettogether. The third example below which runssource("DT_Test.R")on OSX/R 3.3/Data table 1.9.7 is where the inconsistency comes.Test Script: DT_Test.R
1: Results for Linux R 3.3 with data.table 1.9.7 (NO PROBLEMS, all vectors passed of length 1 except for SCALE_SCORE)
2: Results for OSX R 3.3 with data.table 1.9.6 (NO PROBLEMS, all vectors passed of length 1 except for SCALE_SCORE)
3: Results for OSX R 3.3 with data.table 1.9.7 (PROBLEMS with Test #2 below, all vectors passed of length 50)