Adding rows and filling them based on values in column

Hi there,
I am very new to R and have not been able to find the answer to my question:
I have a table with experiments that were performed under specific conditions. For each condition, I have one row with the number of experiments that occurred (e.g. 17) and the number of experiments that were successful (e.g. 3). I want to adapt my dataset, so that for each experiment there is a separate row (ergo 17 rows) and for a number of rows (ergo 3 rows) a new column says that the experiment was a "success" and for the other rows (ergo 14) the experiment was a "fail". How can I do this?

For example, I want to go from this:
Temp RH Experiments Success
15 95 3 2
10 85 2 0
5 85 4 1

To this:
Temp RH Result
15 95 success
15 95 success
15 95 fail
10 85 fail
10 85 fail
5 85 success
5 85 fail
5 85 fail
5 85 fail

Thanks in advance

This was surprisingly tricky! There may be a much easier way of doing this than I have.

library(tidyverse)

dat = tribble(
  ~Temp, ~RH, ~Experiments, ~Success,
  15, 95, 3, 2,
  10, 85, 2, 0,
  5, 85, 4, 1
)

make_rows = function(temp, rh, times, n_succ){
  
  df = data.frame(temp = temp, rh = rh)

  df = slice(df, rep(1, each = times))
  
  vec = c(rep("success", n_succ), rep("fail", nrow(df) - n_succ))
  
  df %>% mutate(result = vec)
  
}

pmap_dfr(.l = dat,
         .f = ~make_rows(temp = ..1, rh = ..2, times = ..3, n_succ = ..4))

Here I've written a function that takes a temperature, relative humidity, a number of repeats and the number of successes and creates a dataframe.

Then I map this function to the data from your original data frame, which seems to create the output that you wanted:

> pmap_dfr(.l = dat,
+          .f = ~make_rows(temp = ..1, rh = ..2, times = ..3, n_succ = ..4))
  temp rh  result
1   15 95 success
2   15 95 success
3   15 95    fail
4   10 85    fail
5   10 85    fail
6    5 85 success
7    5 85    fail
8    5 85    fail
9    5 85    fail

This is a more straightforward method (it may be possible to simplify further):

library(tidyverse)

dat = tribble(
  ~Temp, ~RH, ~Experiments, ~Success,
  15, 95, 3, 2,
  10, 85, 2, 0,
  5, 85, 4, 1
)

dat %>% 
  uncount(Experiments) %>% 
  group_by(Temp, RH) %>% 
  mutate(Result = ifelse(row_number() <= Success, "success", "fail")) %>% 
  ungroup() %>% 
  select(-Success)
2 Likes

This worked perfectly. Thank you very much!