pharmaR / riskmetric

Metrics to evaluate the risk of R packages
https://pharmar.github.io/riskmetric/
Other
156 stars 29 forks source link

Error when using rbind() on pkg_score() outputs #340

Open fh-kpikhart opened 2 months ago

fh-kpikhart commented 2 months ago

I noticed this error when trying to rbind pkg_score() outputs. It seems to be caused by the presence of the pkg_ref column:

library(dplyr)
library(riskmetric)
packageVersion("riskmetric")

[1] ‘0.2.4’

score1 <- "dplyr" %>%
  pkg_ref(source = "pkg_cran_remote", repos = c("https://cran.rstudio.com")) %>%
  as_tibble() %>%
  pkg_assess(all_assessments[1:2]) %>%
  pkg_score()

score2 <- "ggplot2" %>%
  pkg_ref(source = "pkg_cran_remote", repos = c("https://cran.rstudio.com")) %>%
  as_tibble() %>%
  pkg_assess(all_assessments[1:2]) %>%
  pkg_score()

rbind(score1, score2) # doesn't work

Error in `vec_slice()`:
! `x` must be a vector, not a <pkg_cran_remote/pkg_remote/pkg_ref/environment> object.
Run `rlang::last_trace()` to see where the error occurred.

rbind(
  select(score1, !pkg_ref),
  select(score2, !pkg_ref)
) # works

# A tibble: 2 × 5
  package version pkg_score bugs_status covr_coverage
  <chr>   <chr>       <dbl> <pkg_scor>  <pkg_scor>   
1 dplyr   1.1.4       0.783 0.4333333   NA           
2 ggplot2 3.5.1       0.65  0.7000000   NA  
thisisnic commented 1 month ago

I took a look at the stack trace from this error and this is what I got:

> rlang::last_trace()
<error/vctrs_error_scalar_type>
Error in `vec_slice()`:
! `x` must be a vector, not a <pkg_cran_remote/pkg_remote/pkg_ref/environment> object.
---
Backtrace:
     ▆
  1. ├─base::rbind(score1, score2)
  2. │ └─base::rbind(deparse.level, ...)
  3. │   ├─base::`[<-`(`*tmp*`, ri, value = `<lst_f_p_>`)
  4. │   └─vctrs:::`[<-.vctrs_list_of`(`*tmp*`, ri, value = `<lst_f_p_>`)
  5. │     └─vctrs:::map(value, vec_cast, to = wrapped_type)
  6. │       └─base::lapply(.x, .f, ...)
  7. │         └─vctrs (local) FUN(X[[i]], ...)
  8. └─vctrs (local) `<fn>`()
  9.   └─vctrs::vec_default_cast(...)
 10.     └─vctrs:::is_same_type(x, to)
 11.       └─vctrs::vec_slice(x, integer())
Run rlang::last_trace(drop = FALSE) to see 3 hidden frames.

Other folks have a similar issue with {vctrs} which is a dependency of {dplyr}; there are multiple issues open on their repo referencing it: https://github.com/r-lib/vctrs/issues?q=is%3Aissue+is%3Aopen+rbind, but the source of the problem is unclear.

As a workaround, how about using dplyr::bind_rows() instead of rbind()? I've had a similar problem recently using rbind() on a tibble containing a column with a particular S3 class, and that's been the quickest solution for me!

fh-mthomson commented 1 month ago

Confirming that dplyr::bind_rows() works perfectly well. Thanks for the tip!

After fixing a typo in the initial example:

library(dplyr, quietly = TRUE, warn.conflicts = FALSE)
library(riskmetric)
packageVersion("riskmetric")
#> [1] '0.2.4'

get_pkg_score <- function(this_package){
  this_package %>%
    pkg_ref(source = "pkg_cran_remote", repos = c("https://cran.rstudio.com")) %>%
    as_tibble() %>%
    pkg_assess(all_assessments()[1:2]) %>%
    pkg_score()
}
score1 <- get_pkg_score("dplyr")

score2 <- get_pkg_score("ggplot2")

dplyr::bind_rows(score1, score2)
#> # A tibble: 2 × 6
#>   package version pkg_ref              pkg_score bugs_status covr_coverage
#>   <chr>   <chr>   <lst_f_p_>               <dbl> <pkg_scor>  <pkg_scor>   
#> 1 dplyr   1.1.4   dplyr<cran_remote>        0.65 0.7         NA           
#> 2 ggplot2 3.5.1   ggplot2<cran_remote>      0.75 0.5         NA
rbind(score1, score2)
#> Error in `vec_slice()`:
#> ! `x` must be a vector, not a <pkg_cran_remote/pkg_remote/pkg_ref/environment> object.

Created on 2024-05-16 with reprex v2.1.0

PS chiming in on Karina's behalf, since she's no longer at our company - feel free to tag me directly in any threads!