joshuaulrich / xts

Extensible time series class that provides uniform handling of many R time series classes by extending zoo.
http://joshuaulrich.github.io/xts/
GNU General Public License v2.0
220 stars 71 forks source link

Excluding the last column adds NA column #355

Open MortenGrum opened 3 years ago

MortenGrum commented 3 years ago

Description

Excluding the last column of an xts correctly leads to ncol() returning zero but at the same time introduces a new unnamed column with value NA.

Is this a bug?

Expected behavior

I would have expected an xts with same index and no columns.

Minimal, reproducible example

> my_xts <- xts(x=rep(1,5), order.by=Sys.Date()-1:5)
> names(my_xts) = "My Column"
> head(my_xts)
           My Column
2021-06-27         1
2021-06-28         1
2021-06-29         1
2021-06-30         1
2021-07-01         1
> ncol(my_xts)
[1] 1
> my_xts = my_xts[, colnames(my_xts) != "My Column"]
> head(my_xts)
           [,1]
2021-06-27   NA
2021-06-28   NA
2021-06-29   NA
2021-06-30   NA
2021-07-01   NA
> ncol(my_xts)
[1] 0
> 

Session Info

I am working with xts_0.12.1 in R 4.1.0:

R version 4.1.0 (2021-05-18)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19042)

Matrix products: default

locale:
[1] LC_COLLATE=English_Denmark.1252  LC_CTYPE=English_Denmark.1252   
[3] LC_MONETARY=English_Denmark.1252 LC_NUMERIC=C                    
[5] LC_TIME=English_Denmark.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] XML_3.99-0.6       readr_1.4.0        yaml_2.2.1         tmap_3.3-1        
 [5] R.utils_2.10.1     R.oo_1.24.0        R.methodsS3_1.8.1  stringi_1.6.2     
 [9] influxdbr_0.14.2   rmarkdown_2.8      RcppAlgos_2.4.1    nnls_1.4          
[13] maptools_1.1-1     sf_0.9-8           raster_3.4-10      rgeos_0.5-5       
[17] zip_2.1.1          rgdal_1.5-23       sp_1.4-5           plyr_1.8.6        
[21] RColorBrewer_1.1-2 dygraphs_1.1.1.6   reticulate_1.20    jsonlite_1.7.2    
[25] RCurl_1.98-1.3     httr_1.4.2         testthat_3.0.2     xts_0.12.1        
[29] zoo_1.8-9          Rcpp_1.0.6         R6_2.5.0          

loaded via a namespace (and not attached):
 [1] bitops_1.0-7            lubridate_1.7.10        rprojroot_2.0.2        
 [4] tools_4.1.0             utf8_1.2.1              KernSmooth_2.23-20     
 [7] DBI_1.1.1               withr_2.4.2             tidyselect_1.1.1       
[10] leaflet_2.0.4.1         curl_4.3.1              compiler_4.1.0         
[13] leafem_0.1.6            cli_2.5.0               gstat_2.0-7            
[16] desc_1.3.0              classInt_0.4-3          proxy_0.4-25           
[19] digest_0.6.27           foreign_0.8-81          base64enc_0.1-3        
[22] dichromat_2.0-0         pkgconfig_2.0.3         htmltools_0.5.1.1      
[25] htmlwidgets_1.5.3       rlang_0.4.11            rstudioapi_0.13        
[28] FNN_1.1.3               generics_0.1.0          crosstalk_1.1.1        
[31] dplyr_1.0.6             magrittr_2.0.1          Matrix_1.3-3           
[34] waldo_0.2.5             fansi_0.5.0             abind_1.4-5            
[37] lifecycle_1.0.0         leafsync_0.1.0          tmaptools_3.1-1        
[40] grid_4.1.0              parallel_4.1.0          crayon_1.4.1           
[43] lattice_0.20-44         stars_0.5-2             hms_1.1.0              
[46] knitr_1.33              pillar_1.6.1            spacetime_1.2-4        
[49] codetools_0.2-18        pkgload_1.2.1           glue_1.4.2             
[52] evaluate_0.14           leaflet.providers_1.9.0 png_0.1-7              
[55] vctrs_0.3.8             purrr_0.3.4             tidyr_1.1.3            
[58] rematch2_2.1.2          xfun_0.23               mime_0.10              
[61] lwgeom_0.2-6            e1071_1.7-7             class_7.3-19           
[64] viridisLite_0.4.0       tibble_3.1.2            intervals_0.15.2       
[67] diffobj_0.3.4           units_0.7-1             gmp_0.6-2              
[70] ellipsis_0.3.2

Thanks.

joshuaulrich commented 3 years ago

Thanks for the report! It looks like there are multiple bugs here...

You should be able to subset xts objects by selecting none of the columns. That should return a zero-width xts object (an object with an index but no columns). That happens, but the resulting object doesn't have the correct tzone or tclass from the object that was subset.

Then, head() returns an object that has a column of NA, as you showed. That's a bug in head() (and tail()). Strangely, that doesn't happen with first() and last().

joshuaulrich commented 1 year ago

...subset xts objects by selecting none of the columns. ...but the resulting object doesn't have the correct tzone or tclass from the object that was subset. A subset that selects none of the columns now returns an xts object with the same tclass and tzone (related to #255 and #359).


I'm not sure whether or not this is a bug in head() and tail(). There are no xts methods for those functions, so head.zoo() and tail.zoo() are dispatched. Those functions depend on how subsetting zero-width xts/zoo objects work.

Subsetting a zero-width xts object without providing j returns an xts object with one column of NA. This is consistent with zoo. But subsetting a zero-width xts object with a value for j returns a zero-width xts object. This is not consistent with zoo, which again returns an object with one column of NA. @ggrothendieck, @zeileis what are your thoughts on this?