Search code examples
rtidyverse

How can I multiply all the values within a column range and row range?


I have a df that looks like this:

Name No1 No2 No 3
Jack 10 20 30
Eli 10 20 30
Mae 10 20 30
Jack 10 20 30

I want to multiply all values by a factor of 10 in columns 2:4 (so all columns excluding the Name column) and I only want to select rows where Name == Jack.

so, my final data table should look like this:

Name No1 No2 No 3
Jack 100 200 300
Eli 10 20 30
Mae 10 20 30
Jack 100 200 300

I've tried various iterations of the following:

df %>% 
         filter(Name == "Jack") %>% 
         select(No1:No3) %>%
         df*10

including

df %>% 
         filter(Name == "Jack") %>% 
         df[2:4]*10

and I've also tried and if statement:

new_df <- if(df$name == "Jack"){
          df[2:4]*10}

Solution

  • We may use across to loop over the columns that starts with 'No', then create a logical condition based on the 'Name' column, use either ifelse/if_else or case_when to do the change based on the logic

    library(dplyr)
    df <- df %>% 
      mutate(across(c(No1, No2, No3),
        ~ case_when(Name == "Jack" ~ .x * 10, TRUE ~ as.numeric(.x))))
    

    It can be passed as an index as well

    df %>%
        mutate(across(c(2, 3, 4), # or if it is a range 2:4
            ~ case_when(Name == "Jack" ~ .x * 10, TRUE ~ as.numeric(.x))))
    

    Or in base R, subset the columns and the rows (based on the logic), and assign back after multiplying with 10

    df[df$Name == "Jack", -1] <- df[df$Name == "Jack", -1] * 10
    

    data

    df <- structure(list(Name = c("Jack", "Eli", "Mae", "Jack"), No1 = c(10L, 
    10L, 10L, 10L), No2 = c(20L, 20L, 20L, 20L), No3 = c(30L, 30L, 
    30L, 30L)), class = "data.frame", row.names = c(NA, -4L))