The data:
df <- tribble(
~name, ~val.I, ~val.V, ~`val.%`,
"Peter", 123, 12.4, 14,
"Peter in %", 111, 532, 57,
"Harald", 2222, 3333, 444,
"Harald in %", 22, 15, 203,
)
I would like to mutate (function: divide the value by 100) that contain .I
and .V
, but only for rows that contain the string in %
in the column name. I know an easy for-loop solution, but could not figure out it with dplyr
. Any hints much appreciated! :)
CodePudding user response:
A dplyr
option with mutate
and across
using matches
for the specific columns. You can use the following code:
library(dplyr)
df %>%
mutate(across(matches(".I|.V"), ~ if_else(row_number() %in% grep("in %", name), ./100, .)))
Output:
# A tibble: 4 × 4
name val.I val.V `val.%`
<chr> <dbl> <dbl> <dbl>
1 Peter 123 12.4 14
2 Peter in % 1.11 5.32 57
3 Harald 2222 3333 444
4 Harald in % 0.22 0.15 203
CodePudding user response:
A possible solution in base R
:
library(tibble)
df <- tribble(
~name, ~val.I, ~val.V, ~`val.%`,
"Peter", 123, 12.4, 14,
"Peter in %", 111, 532, 57,
"Harald", 2222, 3333, 444,
"Harald in %", 22, 15, 203,
)
df[grepl("in \\%",df$name), grep(".V|.I", names(df))] <-
df[grepl("in \\%",df$name), grep(".V|.I", names(df))] /100
#> # A tibble: 4 × 4
#> name val.I val.V `val.%`
#> <chr> <dbl> <dbl> <dbl>
#> 1 Peter 123 12.4 14
#> 2 Peter in % 1.11 5.32 57
#> 3 Harald 2222 3333 444
#> 4 Harald in % 0.22 0.15 203
With dplyr
:
library(dplyr)
df %>%
mutate(across(contains(c(".V",".I")), ~ if_else(grepl("in \\%",name), .x/100, .x)))
#> # A tibble: 4 × 4
#> name val.I val.V `val.%`
#> <chr> <dbl> <dbl> <dbl>
#> 1 Peter 123 12.4 14
#> 2 Peter in % 1.11 5.32 57
#> 3 Harald 2222 3333 444
#> 4 Harald in % 0.22 0.15 203