[Rd] as.list.factor() should shift input names onto the resulting list

Davis Vaughan d@v|@ @end|ng |rom r@tud|o@com
Wed Oct 20 18:30:41 CEST 2021


Hi all,

The current implementation of as.list.factor() looks like:

as.list.factor
#> function (x, ...)
#> {
#>     res <- vector("list", length(x))
#>     for (i in seq_along(x)) res[[i]] <- x[i]
#>     res
#> }
#> <bytecode: 0x7fa11d146cc0>
#> <environment: namespace:base>

I believe this is incorrect, as names of `x` are not shifted onto `res`.
This results in the behavior shown below, which I am fairly certain is
incorrect (compared to Date methods and other classes). It also affects the
output of lapply().

I believe that as.list.factor() could be rewritten to be more like either
as.list.Date() or as.list.POSIXct(), which would fix the issue.

x <- factor(c("f1", "f2"))
names(x) <- c("a", "b")

y <- as.Date("2019-01-01") + 0:1
names(y) <- c("a", "b")

# Incorrect behavior:
# - Names are kept on inner elements
# - Names are not propagated onto resulting list
as.list(x)
#> [[1]]
#>  a
#> f1
#> Levels: f1 f2
#>
#> [[2]]
#>  b
#> f2
#> Levels: f1 f2

# Correct behavior:
# - Names are stripped from inner elements
# - Names are propagated onto resulting list
as.list(y)
#> $a
#> [1] "2019-01-01"
#>
#> $b
#> [1] "2019-01-02"

# The factor behavior breaks the lapply() invariant that names
# of `X` will be propagated onto the result
lapply(x, identity)
#> [[1]]
#>  a
#> f1
#> Levels: f1 f2
#>
#> [[2]]
#>  b
#> f2
#> Levels: f1 f2

# This works correctly
lapply(y, identity)
#> $a
#> [1] "2019-01-01"
#>
#> $b
#> [1] "2019-01-02"

Thanks,
Davis Vaughan

	[[alternative HTML version deleted]]



More information about the R-devel mailing list