1

So, i don't know if the title makes it easy to understand, but basically i want to change this to the minimum of code possible:

data %>% 
group_by(name) %>%
mutate(
    plataforma.3DS = sum(plataforma.3DS),
    plataforma.PS3 = sum(plataforma.PS3),
    plataforma.PS4 = sum(plataforma.PS4),
    plataforma.PSP = sum(plataforma.PSP),
    plataforma.PSV = sum(plataforma.PSV),
    plataforma.Wii = sum(plataforma.Wii),
    plataforma.WiiU = sum(plataforma.WiiU),
    plataforma.X360 = sum(plataforma.X360),
    plataforma.XOne = sum(plataforma.XOne)   
)

I have some other columns that i need to do this, so how can i reduce my code? thanks in advance.

  • It is impossible to tell without seeing the structure of your data frame. From the context, I think it is very likely that you're looking for `pivot_longet()` to get `plataforma` as column, then you want to `group_by()` it and `summarize()` with sum. – VFreguglia Feb 15 '21 at 20:11

1 Answers1

1

We can specify it with across. Note that mutate replaces the column value with the sum of that column.

library(dplyr)
data %>%
   group_by(name) %>%
   mutate(across(starts_with('plataforma'), sum))

It the intention is to return a single sum per each column, change the mutate to summarise

data %>%
   group_by(name) %>%
   summarise(across(starts_with('plataforma'), sum), .groups = 'drop')

NOTE: The title specified row sum, while the code showed in OP's post is doing column sum.

akrun
  • 874,273
  • 37
  • 540
  • 662
  • @BrunoHenriqueRodrigues Yes, you can create new columns by specifying `.names = "{.col}_new"` in `mutate/summarise` `across` – akrun Feb 15 '21 at 21:28
  • like a charm, thanks! by the way, can i do something similar to create some columns? Mine is like: `data %>% mutate( plataforma.3DS = str_detect(plataforma, regex("3DS", ignore_case = T)), plataforma.PS3 = str_detect(plataforma, regex("PS3", ignore_case = T)), plataforma.PS4 = str_detect(plataforma, regex("PS4", ignore_case = T)) plataforma.PSV = str_detect(plataforma, regex("PSV", ignore_case = T)) )` I'm trying to find something using `help(across)`, but no sucess – Bruno Henrique Rodrigues Feb 15 '21 at 21:34
  • @BrunoHenriqueRodrigues I guess you are doing this on the same column right? – akrun Feb 15 '21 at 21:37
  • @BrunoHenriqueRodrigues If it is on the same column, do `map_dfc(c("3DS", "PS3", ...), ~ data %>% transmute(!! str_c('plataforma\\.', .x) := str_detect(plataforma, regex(.x, ignore_case = TRUE)))) %>% bind_cols(data, .)` – akrun Feb 15 '21 at 21:39
  • i'm getting this: `Error: Input must be a vector, not a function.`. Can you help? – Bruno Henrique Rodrigues Feb 15 '21 at 22:45
  • @BrunoHenriqueRodrigues have you changed the `...` to actual values. i.e. `map(c("3DS", "PS3"), ~ data %>% transmute(!! str_c('plataforma.", .x) := str_detect(plataforma, regex(.x, ignore_case = TRUE))))` can you test if this returns error – akrun Feb 15 '21 at 22:46
  • yes, i tried with c(...) and also storing the values, neither of them works – Bruno Henrique Rodrigues Feb 15 '21 at 22:50
  • @BrunoHenriqueRodrigues you meant, it is not returning output or is there an error – akrun Feb 15 '21 at 22:50
  • still getting error message – Bruno Henrique Rodrigues Feb 15 '21 at 22:50
  • @BrunoHenriqueRodrigues let me show an example that can be reproduced. i.e. ` – akrun Feb 15 '21 at 22:52
  • @BrunoHenriqueRodrigues this works, `data <- data.frame(plataforma = c('3DS_45', 'PS35', '2DS', '42_3DS')); out <- map_dfc(c("3DS", "PS3"), ~ data %>% transmute(!! str_c('plataforma.', .x) := str_detect(plataforma, regex(.x, ignore_case = TRUE)))) %>% bind_cols(data, .)` and checking `dim(out)# [1] 4 3` – akrun Feb 15 '21 at 22:55
  • 1
    many thanks my friend! – Bruno Henrique Rodrigues Feb 15 '21 at 23:58