Reputation: 99
I have a data frame 'df' as below,
R0 <- c('A','B','C','D','E','F')
R1 <- c(15515.88,5156.04,65656,1566.1,11,56)
R2 <- c(515,5156.11,415,1455,47,335)
R3 <- c(123.14,9875,1247,778.04,1445,6645)
R4 <- c(115.88,56.04,6556,166,545,998)
R5 <- c('XX-XX',"AA-AA","VV-VV","YY-YY", 'XX-XX Component', 'YY-YY Component')
df <- data.frame(R0,R1,R2,R3,R4,R5)
Where I need to multiply R1 to R4 by '-1' if R5's first 5 char are 'XX-XX' or 'YY-YY'. I did the below coding which works fine too,
library(operators)
d1 <- df2[stringr::str_extract(df2$R5, "^.{5}") %in% c("XX-XX", "YY-YY"),]
d2 <- df2[stringr::str_extract(df2$R5, "^.{5}") %!in% c("XX-XX", "YY-YY"),]
d1[,2:5] <- d1[,2:5]*(-1)
dff <- rbind(d1,d2)
The output is as expected in 'dff', but is there a simple way rather splitting data frames into two and then rbind.
Upvotes: 1
Views: 72
Reputation: 389012
In base R, you can use:
df[2:5] <- df[2:5] * c(1, -1)[grepl('^(XX-XX|YY-YY)', df$R5) + 1]
df
# R0 R1 R2 R3 R4 R5
#1 A -15515.88 -515.00 -123.14 -115.88 XX-XX
#2 B 5156.04 5156.11 9875.00 56.04 AA-AA
#3 C 65656.00 415.00 1247.00 6556.00 VV-VV
#4 D -1566.10 -1455.00 -778.04 -166.00 YY-YY
#5 E -11.00 -47.00 -1445.00 -545.00 XX-XX Component
#6 F -56.00 -335.00 -6645.00 -998.00 YY-YY Component
We multiply by -1 if R5
starts with XX-XX
or YY-YY
.
Upvotes: 2
Reputation: 39858
One dplyr
option could be:
df %>%
mutate(across(R1:R4, ~ if_else(substr(R5, 1, 5) %in% c("XX-XX", "YY-YY"), . * -1, .)))
R0 R1 R2 R3 R4 R5
1 A -15515.88 -515.00 -123.14 -115.88 XX-XX
2 B 5156.04 5156.11 9875.00 56.04 AA-AA
3 C 65656.00 415.00 1247.00 6556.00 VV-VV
4 D -1566.10 -1455.00 -778.04 -166.00 YY-YY
5 E -11.00 -47.00 -1445.00 -545.00 XX-XX Component
6 F -56.00 -335.00 -6645.00 -998.00 YY-YY Component
Upvotes: 4