Skip to content

[ mistakenly returns rows, not columns, when subsetting with i and specifying drop #307

Closed
@DavisVaughan

Description

@DavisVaughan

I don't think this is intended behavior, and it is actually causing an issue for me in tibbletime. Here's the simple version.


In base R, specifying drop with a data frame is ignored and the column is returned.

# Iris column subsetting
head(iris[1])
#>   Sepal.Length
#> 1          5.1
#> 2          4.9
#> 3          4.7
#> 4          4.6
#> 5          5.0
#> 6          5.4

# Specifying drop still returns the column
head(iris[1, drop = FALSE])
#> Warning in `[.data.frame`(iris, 1, drop = FALSE): 'drop' argument will be
#> ignored
#>   Sepal.Length
#> 1          5.1
#> 2          4.9
#> 3          4.7
#> 4          4.6
#> 5          5.0
#> 6          5.4

In tibble, if drop is specified it is ignored but it treats i like you are wanting to subset by rows, not columns.

# iris tbl
library(tibble)
iris_tbl <- as_tibble(iris)

# This works as intended
iris_tbl[1]
#> # A tibble: 150 x 1
#>    Sepal.Length
#>           <dbl>
#>  1         5.10
#>  2         4.90
#>  3         4.70
#>  4         4.60
#>  5         5.00
#>  6         5.40
#>  7         4.60
#>  8         5.00
#>  9         4.40
#> 10         4.90
#> # ... with 140 more rows

# This returns rows not columns
iris_tbl[1, drop = FALSE]
#> # A tibble: 1 x 5
#>   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#>          <dbl>       <dbl>        <dbl>       <dbl> <fctr> 
#> 1         5.10        3.50         1.40       0.200 setosa

# Same thing but with two columns and drop=TRUE
iris_tbl[c(1,3)]
#> # A tibble: 150 x 2
#>    Sepal.Length Petal.Length
#>           <dbl>        <dbl>
#>  1         5.10         1.40
#>  2         4.90         1.40
#>  3         4.70         1.30
#>  4         4.60         1.50
#>  5         5.00         1.40
#>  6         5.40         1.70
#>  7         4.60         1.40
#>  8         5.00         1.50
#>  9         4.40         1.40
#> 10         4.90         1.50
#> # ... with 140 more rows

# Correctly displays warning, but returns rows
iris_tbl[c(1,3), drop = TRUE]
#> Warning: drop ignored
#> # A tibble: 2 x 5
#>   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#>          <dbl>       <dbl>        <dbl>       <dbl> <fctr> 
#> 1         5.10        3.50         1.40       0.200 setosa 
#> 2         4.70        3.20         1.30       0.200 setosa

The issue seems to be coming from the use of if (nargs() <= 2L) in tbl-df.R. When drop is specified, then the number of args becomes 3. Is there another way to check for what you want here? It seems like you just want something like if( !missing(i) & missing(j) ) but I don't think that is a drop in replacement by itself.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions