4

I have three columns in a data frame in which I want to list all the possible combinations for each column variable: Condition, level and Response.

Df <- data.frame(
  Condition = c(rep("No", 20), rep("Yes",20)),
  Level = c(rep(1,10),rep(2,10),rep(1,10),rep(2,10)),
  Response = c(rep("Excellent",5),rep("Good",5),rep("Average",5), rep("Bad",5))
  )

> Df
   Condition Level  Response
1         No     1 Excellent
2         No     1 Excellent
:          :     :        :
39       Yes     2       Bad
40       Yes     2       Bad

Here is an example of a desired output. I could use a nested for-loop and shorten this code. But i'm not looking for a for-loop as i'm sure there is a more efficient way to do this!

Output <- list()

Output[[1]] <- data.frame(
  Condition = c(rep("No",5)),
  Level = c(rep(1,5)),
  Response = c(rep("Excellent",5))
)
Output[[2]] <- data.frame(
  Condition = c(rep("No",5)),
  Level = c(rep(1,5)),
  Response = c(rep("Good",5))
)
#All possible combination till Output[[8]]
Output[[8]] <- data.frame(
  Condition = c(rep("Yes",5)),
  Level = c(rep(2,5)),
  Response = c(rep("Bad",5))


> Output
[[1]]
  Condition Level  Response
1        No     1 Excellent
2        No     1 Excellent
3        No     1 Excellent
4        No     1 Excellent
5        No     1 Excellent

[[2]]
  Condition Level Response
1        No     1     Good
2        No     1     Good
3        No     1     Good
4        No     1     Good
5        No     1     Good
:
[[8]]
  Condition Level Response
1       Yes     2      Bad
2       Yes     2      Bad
3       Yes     2      Bad
4       Yes     2      Bad
5       Yes     2      Bad
Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
Ali
  • 1,048
  • 8
  • 19
  • Possible duplicate https://stackoverflow.com/questions/9713294/split-data-frame-based-on-levels-of-a-factor-into-new-data-frames/ – Ronak Shah Sep 17 '19 at 13:09

2 Answers2

3

In base R, you could split the data.frame using the interaction of the columns with drop = TRUE:

split(Df, f = with(Df, interaction(Condition, Level, Response, drop = TRUE))

or if the (factor level) list names should be lexically ordered:

split(Df, f = with(Df, interaction(Condition, Level, Response, drop = TRUE, lex.order = TRUE)))
Joris C.
  • 5,721
  • 3
  • 12
  • 27
2

You can do it by using the group_split from dplyr.

Df %>% group_split(Condition, Level, Response)
Arienrhod
  • 2,451
  • 1
  • 11
  • 19