How do I get column names when mutating across columns?

I would like to compute one value per row into an additional column. This is the code I'm using:

table <- table %>%
    rowwise() %>%
    mutate(result = compute_result(c_across()))

My compute_result function gets passed a vector of values. However, I need to get access to the column names from within that function. How would I do that without resorting to manually looping around?

I think we need a reproducible example (reprex)


Is this what you mean?

library(tidyverse)

compute_result <- function(x) {
    # I get a vector with numbers here.
    # So this works as expected:
    sum(x)

    # Instead, I would like to get a vector with named values to (e.g.) do
    # something with `names(x)`.
}

mtcars %>%
    rowwise() %>%
    mutate(result = compute_result(c_across())) %>%
    print()
#> # A tibble: 32 x 12
#> # Rowwise: 
#>      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb result
#>    <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>  <dbl>
#>  1  21       6  160    110  3.9   2.62  16.5     0     1     4     4   329.
#>  2  21       6  160    110  3.9   2.88  17.0     0     1     4     4   330.
#>  3  22.8     4  108     93  3.85  2.32  18.6     1     1     4     1   260.
#>  4  21.4     6  258    110  3.08  3.22  19.4     1     0     3     1   426.
#>  5  18.7     8  360    175  3.15  3.44  17.0     0     0     3     2   590.
#>  6  18.1     6  225    105  2.76  3.46  20.2     1     0     3     1   386.
#>  7  14.3     8  360    245  3.21  3.57  15.8     0     0     3     4   657.
#>  8  24.4     4  147.    62  3.69  3.19  20       1     0     4     2   271.
#>  9  22.8     4  141.    95  3.92  3.15  22.9     1     0     4     2   300.
#> 10  19.2     6  168.   123  3.92  3.44  18.3     1     0     4     4   350.
#> # … with 22 more rows

Created on 2021-06-23 by the reprex package (v2.0.0)

library(tidyverse)

head(mtcars,2) %>% rowwise() %>% mutate(result = list(c_across())) %>% pull(result)
mtcarsnames <- names(mtcars)
head(mtcars,2) %>% mutate(rn=row_number()) %>% group_by(rn) %>% nest(all_of(mtcarsnames)) %>% pull(data)
#or even 
head(mtcars,2) %>% rowwise() %>% group_split()

it seems you are angling for something like the second and third ones , so you can feed a data.frame to your function.

I personally find across kind of unintuitive and difficult to debug. nest is more intuitive. It will create a list of data frames with the contents.

iris %>% 
  nest(data = Sepal.Length:Petal.Width) %>% 
  mutate(result = map(data, function(x) colnames(x))) %>% 
  unnest(data)

Obviously in this example, the function is just getting the column names, but you can put your own function there.

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.