Okay, so basically you have a more advanced options imo. This would be to reshape your data and simplify it, to reduce the necessary code. This would involve a few steps (you could reshape you data to long, split the column names to obtain "name + number", then apply a function which applies your desired logic to each subset based on the subset).
Here is the code with a little bit of toy data and I hope I understood the data you have well enough, since you did not provide a full reprex:
set.seed(0)
Data <- data.frame(
fu_cm_taken1 = sample(c(0,1), 50, replace = TRUE),
fu_cm_yn1 = sample(c(0,1), 50, replace= TRUE),
fu_cm1 = sample(c("yay", "ney"), 50, replace = TRUE),
fu_cm_taken2 = sample(c(0,1), 50, replace = TRUE),
fu_cm_yn2 = sample(c(0,1), 50, replace= TRUE),
fu_cm2 = sample(c("yay", "ney"), 50, replace = TRUE)
)
library(data.table)
Data <- as.data.table(Data)
# Reshape to long
Data <- melt.data.table(Data, measure.vars = colnames(Data))
# Split with Regex
Data[, c("Name", "Number") := tstrsplit(variable, "(?<=[a-zA-Z])(?=[[:digit:]])", perl = TRUE)]
# Define function
myFunc <- function(dt) {
dt[, id := 1:.N, Name]
dt |>
dcast.data.table(id ~ Name, value.var = "value") |>
collapse::ftransform(
fu_cm = fifelse(fu_cm_taken != 1 & fu_cm_yn != 1, fu_cm, NA_character_)
) |>
melt.data.table(id.vars = "id") |>
collapse::fselect(- id)
}
# Apply to each subset defined by Number
Data <- Data |>
collapse::rsplit(~ Number) |>
collapse::rapply2d(
myFunc
) |>
collapse::unlist2d() |>
# this returns a data.frame, so convert back, but efficently
collapse::qDT()
# Reshape to original form
Data[, orig_name := paste0(variable, .id)]
Data[, id := 1:.N, .(variable, .id)]
Data[, .id := NULL]
dcast.data.table(Data, id ~ orig_name, value.var = "value")
id fu_cm1 fu_cm2 fu_cm_taken1 fu_cm_taken2 fu_cm_yn1 fu_cm_yn2
1: 1 <NA> ney 1 0 0 0
2: 2 <NA> <NA> 0 1 1 1
3: 3 <NA> <NA> 1 0 0 1
4: 4 <NA> yay 0 0 1 0
5: 5 <NA> <NA> 0 0 1 1
6: 6 <NA> <NA> 1 0 0 1
7: 7 yay <NA> 0 1 0 1
8: 8 <NA> <NA> 0 1 1 0
9: 9 <NA> <NA> 0 1 1 0
10: 10 <NA> <NA> 1 1 1 1
11: 11 <NA> <NA> 1 1 0 0
12: 12 yay ney 0 0 0 0
13: 13 <NA> yay 0 0 1 0
14: 14 <NA> yay 0 0 1 0
15: 15 <NA> <NA> 0 1 1 1
16: 16 <NA> yay 0 0 1 0
17: 17 <NA> ney 1 0 1 0
18: 18 <NA> <NA> 1 1 1 0
19: 19 <NA> <NA> 1 0 0 1
20: 20 <NA> <NA> 1 0 1 1
21: 21 <NA> <NA> 0 1 1 0
22: 22 <NA> <NA> 0 0 1 1
23: 23 <NA> <NA> 0 0 1 1
24: 24 yay <NA> 0 1 0 1
25: 25 yay <NA> 0 0 0 1
26: 26 ney <NA> 0 0 0 1
27: 27 <NA> <NA> 0 1 1 0
28: 28 <NA> <NA> 1 1 1 0
29: 29 ney <NA> 0 1 0 0
30: 30 ney <NA> 0 1 0 0
31: 31 <NA> <NA> 1 0 1 1
32: 32 <NA> <NA> 1 1 1 0
33: 33 <NA> ney 1 0 1 0
34: 34 ney yay 0 0 0 0
35: 35 <NA> ney 1 0 0 0
36: 36 ney ney 0 0 0 0
37: 37 <NA> <NA> 0 0 1 1
38: 38 <NA> <NA> 1 1 0 1
39: 39 <NA> <NA> 0 0 1 1
40: 40 <NA> <NA> 1 1 0 1
41: 41 <NA> <NA> 1 0 1 1
42: 42 <NA> <NA> 1 0 0 1
43: 43 <NA> <NA> 1 1 0 1
44: 44 <NA> ney 0 0 1 0
45: 45 <NA> <NA> 1 1 1 1
46: 46 <NA> <NA> 1 1 0 0
47: 47 <NA> <NA> 1 1 0 1
48: 48 <NA> ney 1 0 0 0
49: 49 <NA> <NA> 1 1 1 1
50: 50 <NA> ney 0 0 1 0
I hope the comments explain the code well enough, if you have questions or don't think this fits your needs, just raise a question and take me. I will try to answer them.