Repository navigation
Reverse dependency tidytable fails due to type mismatch in a merge operation #7604
Description
Activity
This works:
library(data.table) y <- data.table(as.double(2:3), list('foo','bar')) x <- data.table(1:3) y[x, on='V1']
But this doesn't:
(y <- tidytable(x = as.double(2:3), y = list('foo','bar'))) # # A tidytable: 2 × 2 # x y # <dbl> <list> # 1 2 <chr [1]> # 2 3 <chr [1]> (x <- tidytable(x = 1:3)) # # A tidytable: 3 × 1 # x # <int> # 1 1 # 2 2 # 3 3 y[x, on = 'x'] # Error in bmerge(i, x, leftcols, rightcols, roll, rollends, nomatch, mult, : # typeof x.x (double) != typeof i.x (integer)
In the second example,
xandyare not completely valid (missing the self-reference attribute, not growable). Installing the development version oftidytablefixes the problem, probably due to markfairbanks/tidytable#840.The problem is due to
bmerge→coerce_col→setchanging thedata.tablein the call frame forcoerce_colbut notbmerge:
Line 25 in 35dbf06
set(dt, j=col, value=cast_with_attrs(dt[[col]], cast_fun)) Should
bmergeadd a check forselfrefokandsetalloccolbefore callingcoerce_col?A more systematic check for internal use of
set()reveals that almost all calls are with a properly intialiseddata.table, usually created a few lines above, or at least something that is not shared with the caller. The only suspect uses are insetdroplevels
Line 26 in 35dbf06
set(x, i=NULL, j=nx, value=fdroplevels(x[[nx]], exclude=exclude))
andbmerge:
Line 25 in 35dbf06
set(dt, j=col, value=cast_with_attrs(dt[[col]], cast_fun)) Indeed,
setdroplevelssilently doesn't work on invaliddata.tables:x <- structure(list(factor('a', levels = letters)), class = c('data.table', 'data.frame'), names = 'x') setdroplevels(x) levels(x$x) # [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" # [20] "t" "u" "v" "w" "x" "y" "z"
Should we:
- make the behaviour of
set()closer to how it used to work, only requiringsetalloccolwhen changing the number of columns, or - change
setdroplevelsandcoerce_colto propagate the re-createddata.tableto the caller?
- make the behaviour of
Found while selectively checking reverse dependencies before the 1.18.2 release:
Bisects to 85a4cf5 (#7538).