 # 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

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!