CronAcronis - 6 months ago 53

R Question

I am lost with evaluation of

`by`

`data.table`

`LJ`

`LJ2`

`LJ <- function(dt_x_, dt_y_, by_)`

{

merge(

dt_x_,

dt_y_,

by = eval(substitute(by_)), all.x = TRUE, sort = FALSE)

}

LJ2 <- function(dt_x_, dt_y_, by_)

{

merge(

dt_x_,

dt_y_,

by = deparse(substitute(by_)), all.x = TRUE, sort = FALSE)

}

LJ(

data.table(A = c(1,2,3)),

data.table(A = c(1,2,3), B = c(11,12,13)),

"A")

LJ2(

data.table(A = c(1,2,3)),

data.table(A = c(1,2,3), B = c(11,12,13)),

A)

Answer

I consider this a bad idea. Have the user always pass a character value. You could do this:

```
LJ3 <- function(dt_x_, dt_y_, by_)
{
by_ <- gsub('\"', "", deparse(substitute(by_)), fixed = TRUE)
dt_y_[dt_x_, on = by_]
}
LJ3(
data.table(A = c(4,1,2,3)),
data.table(A = c(1,2,3), B = c(11,12,13)),
A)
# A B
#1: 4 NA
#2: 1 11
#3: 2 12
#4: 3 13
LJ3(
data.table(A = c(4,1,2,3)),
data.table(A = c(1,2,3), B = c(11,12,13)),
"A")
# A B
#1: 4 NA
#2: 1 11
#3: 2 12
#4: 3 13
```

This question is not related to data.table. The `by`

parameter in `merge.data.table`

always expects a character value, as does `on`

.

**Edit:** @eddi points out that the above will fail if you have column names with actual `"`

in them (something you should avoid in general, but may happen if you `fread`

some input files prepared by others).

An alternative that can handle such edge cases would be:

```
LJ4 <- function(dt_x_, dt_y_, by_)
{
by_ <- substitute(by_)
if (!is.character(by_)) by_ <- deparse(by_)
dt_y_[dt_x_, on = by_]
}
```