Here is an option with melt
from data.table
library(data.table)
melt(setDT(df), measure = patterns("^Machine", "^Sales", "^Spoils"),
value.name = c("Machine_adds", "Sales", "Spoils"))[, variable := NULL][]
# Location Product_Name Category Machine_adds Sales Spoils
# 1: A Snickers Candy 0 $2.5 2
# 2: A Kitcat Candy 0 $3 2
# 3: A Pepsi Bev 1 $5 3
# 4: B Coke Bev 1 $5 1
# 5: B Gatoraid Bev 0 $4 1
# 6: B Sprite Bev 1 $8 1
# 7: A Snickers Candy 1 $3 1
# 8: A Kitcat Candy 1 $3 1
# 9: A Pepsi Bev 1 $4 0
#10: B Coke Bev 0 $6.45 1
#11: B Gatoraid Bev 1 $4.45 0
#12: B Sprite Bev 1 $6 0
Update
Based on the OP's updated example, if there are 'Machine' and Machine_adds' columns, we can slightly changed the patterns
to
# creating new columns in the dataset
df[c('Machine1', 'Machine2')] <- df[c("Machine1_adds", "Machine2_adds")]
melt(setDT(df), measure = patterns("^Machine\\d+$",
"^Machine\\d+_adds$", "^Sales", "^Spoils"),
value.name = c("Machine", "Machine_adds", "Sales", "Spoils"))[,
variable := NULL][]
Or using pivot_longer
from tidyr
library(dplyr)
library(tidyr)
library(stringr)
df %>%
rename_at(3:ncol(.), ~
str_replace(., "(\\d+)_?.*", "_\\1")) %>%
pivot_longer(cols = matches("^(Machine|Sales|Spoils)"),
names_to = c(".value", "group"), names_sep = "_") %>%
select(-group)
# A tibble: 12 x 6
# Location Product_Name Category Machine Sales Spoils
# <chr> <chr> <chr> <dbl> <chr> <dbl>
# 1 A Snickers Candy 0 $2.5 2
# 2 A Snickers Candy 1 $3 1
# 3 A Kitcat Candy 0 $3 2
# 4 A Kitcat Candy 1 $3 1
# 5 A Pepsi Bev 1 $5 3
# 6 A Pepsi Bev 1 $4 0
# 7 B Coke Bev 1 $5 1
# 8 B Coke Bev 0 $6.45 1
# 9 B Gatoraid Bev 0 $4 1
#10 B Gatoraid Bev 1 $4.45 0
#11 B Sprite Bev 1 $8 1
#12 B Sprite Bev 1 $6 0
Update
df %>%
rename_at(vars(matches('^Machine.*adds$')), ~
str_replace(., '(\\d+)_(\\w+)$', '_\\2\\1')) %>%
rename_at(3:ncol(.), ~ str_replace(., "(\\d+)_?.*", ":\\1")) %>%
pivot_longer(cols = matches("^(Machine|Sales|Spoils)"),
names_to = c(".value", "group"), names_sep = ":") %>%
select(-group)
data
df <- structure(list(Location = c("A", "A", "A", "B", "B", "B"),
Product_Name = c("Snickers",
"Kitcat", "Pepsi", "Coke", "Gatoraid", "Sprite"), Category = c("Candy",
"Candy", "Bev", "Bev", "Bev", "Bev"), Machine1_adds = c(0, 0,
1, 1, 0, 1), Machine2_adds = c(1, 1, 1, 0, 1, 1), Sales1 = c("$2.5",
"$3", "$5", "$5", "$4", "$8"), Sales2 = c("$3", "$3", "$4", "$6.45",
"$4.45", "$6"), Spoils1 = c(2, 2, 3, 1, 1, 1), Spoils2 = c(1,
1, 0, 1, 0, 0)), row.names = c(NA, -6L), class = c("tbl_df",
"tbl", "data.frame"))