I'm looking to loop through all combinations of columns in a data frame and filter out rows where there are values less than zero. I've written most of the code but I'm struggling to input the values of my list into the filter function.
I started by creating my data frame 'df'. I wrote a function to get me all combinations of column names to be used as input into the filter function. I'm using if_all because I only want the rows where all columns are > 0.
Here is an example data frame
library(dplyr)
item1 <- c(-.5, 1.3, .8)
item2 <- c(.9, 2.5, 1.2)
item3 <- c(-1.2, .4, -2.1)
df <- data.frame(item1,item2,item3)
Here are all the combinations of columns I want to loop through
name_combos <- lapply(1:3, function(x) combn(c("item1","item2","item3"), x, simplify = FALSE))
name_combos <- unlist(name_combos, recursive = FALSE)
Here is where I am struggling. I'm looking for the right input so I can loop through name_combos and input each combination of column names where the '?' is.
for (i in 1:length(name_combos)) {
results <- df %>%
filter(if_all(?, ~ . > 0))
print(results)
}
Please let me know if more clarification is needed. Thank you in advance for any help.
CodePudding user response:
From Your name_combo
object, you could do:
name_combos %>%
map(~filter(df, if_all(all_of(.x), ~. > 0)))
[[1]]
item1 item2 item3
1 1.3 2.5 0.4
2 0.8 1.2 -2.1
[[2]]
item1 item2 item3
1 -0.5 0.9 -1.2
2 1.3 2.5 0.4
3 0.8 1.2 -2.1
[[3]]
item1 item2 item3
1 1.3 2.5 0.4
:
:
Note that combn
has a function argument within it, therefore we could do:
In one step, you can do the following:
map(1:3, ~combn(df, .x, \(x)filter(df, invoke(pmin, x)>0), simplify = F))
Of if you want to use if_all
:
map(1:3, ~combn(names(df), .x, \(x) filter(df, if_all(all_of(x), ~.>0)), simplify = F))
You could then unlist
with recursive = FALSE
For the for loop:
results <- list()
for (i in seq_along(name_combos)) {
nms <- name_combos[[i]]
results[[paste0(nms, collapse = "_")]] <- df %>%
filter(if_all(all_of(nms), ~ .> 0))
}
print(results)
$item1
item1 item2 item3
1 1.3 2.5 0.4
2 0.8 1.2 -2.1
$item2
item1 item2 item3
1 -0.5 0.9 -1.2
2 1.3 2.5 0.4
3 0.8 1.2 -2.1
$item3
item1 item2 item3
1 1.3 2.5 0.4
$item1_item2
item1 item2 item3
1 1.3 2.5 0.4
2 0.8 1.2 -2.1