R: Error: `c_across()` must only be used inside dplyr verbs

Viewed 2335
library(tidyverse)
nsource <- 5
mydata <- structure(list(p1 = c(0.153603238035774, 0.251732841184133), 
                         p2 = c(0.0108935803858148, 0.12041117307058), 
                         p3 = c(0.712158280629968, 0.257556345715588), 
                         p4 = c(0.0529741150781822, 0.17690785400165), 
                         p5 = c(0.0703707858702605, 0.193391786028049)), 
                    row.names = 1:2, class = "data.frame")

mydata <- mydata %>% 
  rowwise %>%
  mutate(P = sample(1:nsource, size = 1, replace = TRUE, 
                    prob = c_across(matches('^p\\d+$')))) %>% 
  ungroup
> Error: `c_across()` must only be used inside dplyr verbs.

I have a dataset mydata

         p1         p2        p3         p4         p5
1 0.1536032 0.01089358 0.7121583 0.05297412 0.07037079
2 0.2517328 0.12041117 0.2575563 0.17690785 0.19339179 

where each row contains 5 probabilities that sum up to one. I want to sample a number called "P" from 1:5 w/ probability p1:p5. However, running the above code gives me the error that "c_across() must only be used inside dplyr verbs."

2 Answers

With nsource as 5, it works

library(dplyr)
nsource <- 5
mydata %>%
   rowwise %>%
   dplyr::mutate(P = sample(1:nsource, size = 1, replace = TRUE, 
       c_across(matches('^p\\d+$')))) %>%
   ungroup

-output

# A tibble: 2 x 6
     p1     p2    p3     p4     p5     P
  <dbl>  <dbl> <dbl>  <dbl>  <dbl> <int>
1 0.154 0.0109 0.712 0.0530 0.0704     3
2 0.252 0.120  0.258 0.177  0.193      4

The issue with OP's code could be related to plyr::mutate masking the dplyr::mutate

mydata %>% 
+   rowwise %>%
+   plyr::mutate(P = sample(1:nsource, size = 1, replace = TRUE, 
+                     prob = c_across(matches('^p\\d+$'))))
Error: `c_across()` must only be used inside dplyr verbs.
Run `rlang::last_error()` to see where the error occurred.

The remedy is to specify dplyr::mutate or do this in a new R session with only dplyr loaded

Here is another solution you could use:

library(purrr)

mydata %>%
  mutate(P = pmap_int(select(cur_data(), everything()), ~ sample(1:nsource, 1, TRUE, c(...))))

         p1         p2        p3         p4         p5 P
1 0.1536032 0.01089358 0.7121583 0.05297412 0.07037079 3
2 0.2517328 0.12041117 0.2575563 0.17690785 0.19339179 1
Related