r-lib / vctrs

Generic programming with typed R vectors

Home Page:https://vctrs.r-lib.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

'Internal error' requested report: dplyr::arrange() of expand.grid(NULL, y)

taiawu opened this issue · comments

dplyr::arrange() fails when applied to the output of expand.grid() if the first argument to expand.grid() is NULL.

base version 4.3.1
dplyr version 1.1.3
RStudio Version 2023.09.0+463 (2023.09.0+463)

dplyr::arrange(expand.grid(NULL, LETTERS))
#> Error in `vec_slice()`:
#> ! Unexpected `NULL`.
#> ℹ In file 'slice.c' at line 322.
#> ℹ This is an internal error that was detected in the vctrs package.
#>   Please report it at <https://github.com/r-lib/vctrs/issues> with a reprex (<https://tidyverse.org/help/>) and the full backtrace.
#> Backtrace:
#>      ▆
#>   1. ├─dplyr::arrange(expand.grid(NULL, LETTERS))
#>   2. ├─dplyr:::arrange.data.frame(expand.grid(NULL, LETTERS))
#>   3. │ ├─dplyr::dplyr_row_slice(.data, loc)
#>   4. │ └─dplyr:::dplyr_row_slice.data.frame(.data, loc)
#>   5. │   ├─dplyr::dplyr_reconstruct(vec_slice(data, i), data)
#>   6. │   │ └─dplyr:::dplyr_new_data_frame(data)
#>   7. │   │   ├─row.names %||% .row_names_info(x, type = 0L)
#>   8. │   │   └─base::.row_names_info(x, type = 0L)
#>   9. │   └─vctrs::vec_slice(data, i)
#>  10. └─rlang:::stop_internal_c_lib(...)
#>  11.   └─rlang::abort(message, call = call, .internal = TRUE, .frame = frame)

Created on 2023-09-29 with reprex v2.0.2

Running expand.grid(NULL, LETTERS)in an R Notebook returns an error message, but it doesn't act like a typical error--it returns a data frame anyway, and the code continues to execute.

# error message displays only when run in an R Notebook chunk
expand.grid(NULL, LETTERS)
#> Error in (function (..., row.names = NULL, check.rows = FALSE, check.names = TRUE,  : 
#>   arguments imply differing number of rows: 1, 0

print("code is still running . . . ")
#>  [1] "code is still running . . . "

str(expand.grid(NULL, LETTERS))
#> 'data.frame':    0 obs. of  2 variables:
#>  $ Var2: NULL
#>  $     : chr 
#>  - attr(*, "out.attrs")=List of 2
#>   ..$ dim     : int [1:2] 0 26
#>   ..$ dimnames:List of 2
#>   .. ..$ Var1: NULL
#>   .. ..$ Var2: NULL

I don't see this error message when I run the same line of code in the console, and it also isn't captured by reprex::reprex().

# run in console, with result copied here manually
expand.grid(NULL, LETTERS)
#> [1] Var2     
#> <0 rows> (or 0-length row.names)

Result from reprex::reprex() with expand.grid(NULL, LETTERS) on the clipboard:

expand.grid(NULL, LETTERS)
#> [1] Var2     
#> <0 rows> (or 0-length row.names)

Created on 2023-09-29 with reprex v2.0.2

Even in an R Notebook, I don't see the error if I assign the output ofexpand.grid(NULL, LETTERS).
The resulting object reproduces the original error message from dplyr::arrange().

# no error message displayed when run in notebook chunk or console
expanded <- expand.grid(NULL, LETTERS) 

str(expanded)
#>  'data.frame':	0 obs. of  2 variables:
#>   $ Var2: NULL
#> $     : chr 
#> - attr(*, "out.attrs")=List of 2
#>  ..$ dim     : int [1:2] 0 26
#>  ..$ dimnames:List of 2
#>  .. ..$ Var1: NULL
#>  .. ..$ Var2: NULL

dplyr::arrange(expanded)
#> Error in `vec_slice()`:
#> ! Unexpected `NULL`.
#> ℹ In file 'slice.c' at line 322.
#> ℹ This is an internal error that was detected in the vctrs package.
#>   Please report it at <https://github.com/r-lib/vctrs/issues> with a reprex (<https://tidyverse.org/help/>) and the full backtrace.
#> Backtrace:
#>      ▆
#>   1. ├─dplyr::arrange(expanded)
#>   2. ├─dplyr:::arrange.data.frame(expanded)
#>   3. │ ├─dplyr::dplyr_row_slice(.data, loc)
#>   4. │ └─dplyr:::dplyr_row_slice.data.frame(.data, loc)
#>   5. │   ├─dplyr::dplyr_reconstruct(vec_slice(data, i), data)
#>   6. │   │ └─dplyr:::dplyr_new_data_frame(data)
#>   7. │   │   ├─row.names %||% .row_names_info(x, type = 0L)
#>   8. │   │   └─base::.row_names_info(x, type = 0L)
#>   9. │   └─vctrs::vec_slice(data, i)
#>  10. └─rlang:::stop_internal_c_lib(...)
#>  11.   └─rlang::abort(message, call = call, .internal = TRUE, .frame = frame)

Created on 2023-09-29 with reprex v2.0.2

Displaying / printing the assigned object appears to have the same error message behavior asexpand.grid(NULL, LETTERS)

Run in R Notebook chunk, copied associated output from console:

# no error message when run in either notebook chunk or console
expanded <- expand.grid(NULL, LETTERS)

# error message only if run in notebook chunk (no error msg when run in console)
expanded
#> Error in (function (..., row.names = NULL, check.rows = FALSE, check.names = TRUE,  : 
#>  arguments imply differing number of rows: 1, 0
print("still running")
#> [1] "still running"

# no error message in notebook or console
str(expanded) 
# 'data.frame':	0 obs. of  2 variables:
#  $ Var2: NULL
#  $     : chr 
#  - attr(*, "out.attrs")=List of 2
#   ..$ dim     : int [1:2] 0 26
#   ..$ dimnames:List of 2
#   .. ..$ Var1: NULL
#   .. ..$ Var2: NULL

# error message only if run in notebook chunk (no error msg when run in console)
print(expanded)
#> Error in (function (..., row.names = NULL, check.rows = FALSE, check.names = TRUE,  : 
#>  arguments imply differing number of rows: 1, 0

Other notes, for completion:

# no error in notebook, console, or reprex() when only second argument to grid.expand() is NULL
dplyr::arrange(expand.grid(LETTERS, NULL))
#> [1] Var1
#> <0 rows> (or 0-length row.names)

# two NULL arguments to expand.grid() reproduces the original error
dplyr::arrange(expand.grid(NULL, NULL))
#> Error in `vec_slice()`:
#> ! Unexpected `NULL`.
#> ℹ In file 'slice.c' at line 322.
#> ℹ This is an internal error that was detected in the vctrs package.
#>   Please report it at <https://github.com/r-lib/vctrs/issues> with a reprex (<https://tidyverse.org/help/>) and the full backtrace.
#> Backtrace:
#>      ▆
#>   1. ├─dplyr::arrange(expand.grid(NULL, NULL))
#>   2. ├─dplyr:::arrange.data.frame(expand.grid(NULL, NULL))
#>   3. │ ├─dplyr::dplyr_row_slice(.data, loc)
#>   4. │ └─dplyr:::dplyr_row_slice.data.frame(.data, loc)
#>   5. │   ├─dplyr::dplyr_reconstruct(vec_slice(data, i), data)
#>   6. │   │ └─dplyr:::dplyr_new_data_frame(data)
#>   7. │   │   ├─row.names %||% .row_names_info(x, type = 0L)
#>   8. │   │   └─base::.row_names_info(x, type = 0L)
#>   9. │   └─vctrs::vec_slice(data, i)
#>  10. └─rlang:::stop_internal_c_lib(...)
#>  11.   └─rlang::abort(message, call = call, .internal = TRUE, .frame = frame)

# error is not specific to use of LETTERS as non-NULL argument
dplyr::arrange(expand.grid(NULL, c(1:3)))
#> Error in `vec_slice()`:
#> ! Unexpected `NULL`.
#> ℹ In file 'slice.c' at line 322.
#> ℹ This is an internal error that was detected in the vctrs package.
#>   Please report it at <https://github.com/r-lib/vctrs/issues> with a reprex (<https://tidyverse.org/help/>) and the full backtrace.
#> Backtrace:
#>      ▆
#>   1. ├─dplyr::arrange(expand.grid(NULL, c(1:3)))
#>   2. ├─dplyr:::arrange.data.frame(expand.grid(NULL, c(1:3)))
#>   3. │ ├─dplyr::dplyr_row_slice(.data, loc)
#>   4. │ └─dplyr:::dplyr_row_slice.data.frame(.data, loc)
#>   5. │   ├─dplyr::dplyr_reconstruct(vec_slice(data, i), data)
#>   6. │   │ └─dplyr:::dplyr_new_data_frame(data)
#>   7. │   │   ├─row.names %||% .row_names_info(x, type = 0L)
#>   8. │   │   └─base::.row_names_info(x, type = 0L)
#>   9. │   └─vctrs::vec_slice(data, i)
#>  10. └─rlang:::stop_internal_c_lib(...)
#>  11.   └─rlang::abort(message, call = call, .internal = TRUE, .frame = frame)

Created on 2023-09-29 with reprex v2.0.2

I think the fact that expand.grid(NULL, anything) puts a NULL in the data frame as a column is actually a bug in expand.grid(). NULL columns create a corrupt data frame, and the best thing vctrs can do about that is error, so there isn't anything we can do on our end.

Really that NULL should have been removed from the result like in these other cases

vctrs:::unstructure(expand.grid(NULL))
#> list()

vctrs:::unstructure(expand.grid(1, NULL))
#> [[1]]
#> numeric(0)

vctrs:::unstructure(expand.grid(NULL, 1))
#> [[1]]
#> NULL
#> 
#> [[2]]
#> numeric(0)

I've reported the problem to R-devel