using time intervals to populate a new column

Viewed 177

I have a dataframe:

dataframe <- data.frame(Condition = rep(c(1,2,3), each = 10),
                        Time = rep(c(1,3,7,9,16,18,25,28,29,30), times = 3))

I want to divide the total length of Time (e.g., 30) by 'x' (e.g., x = 3). Then, I want to use the quotient (e.g., 10) as an interval to add a new variable Trial, such that my new dataframe looks like this:

     Condition Time Trial
1          1    1     A
2          1    3     A
3          1    7     A
4          1    9     A
5          1   16     B
6          1   18     B
7          1   25     C
8          1   28     C
9          1   29     C
10         1   30     C
11         2    1     A
12         2    3     A
13         2    7     A
14         2    9     A
15         2   16     B
... and so on

As you can see, every 10 seconds per Condition, Trial is populated with a unique identifying value (e.g., "A").

In my real data set, I can specify 'x' but the Time varies by Condition.

Thanks!

Reproducible dataset for @ktiu

dataframe <- data.frame(Condition = rep(c(1,2,3), each = 5, times = 2),
                        Time = sort(sample(1:60, 30)))
3 Answers

This would be my approach:

library(dplyr)

dataframe %>%
  group_by(Condition) %>%
  mutate(Trial = LETTERS[cut(Time, 3, labels = F)])

Returns:

# A tibble: 30 x 3
# Groups:   Condition [3]
   Condition  Time Trial
       <dbl> <dbl> <chr>
 1         1     1 A    
 2         1     3 A    
 3         1     7 A    
 4         1     9 A    
 5         1    16 B    
 6         1    18 B    
 7         1    25 C    
 8         1    28 C    
 9         1    29 C    
10         1    30 C    
# … with 20 more rows

If Condition is recycled (as suggested in comments) we can implement @akrun's strategy from this question to do

dataframe %>%
  mutate(condition_seq = with(rle(dataframe$Condition),
                              rep(seq_along(values), lengths))) %>%
  group_by(condition_seq) %>%
  mutate(Trial = LETTERS[cut(Time, 3, labels = F)]) %>%
  ungroup() %>%
  select(-condition_seq)

Data used:

dataframe <- data.frame(Condition = rep(c(1,2,3), each = 10), Time = rep(c(1,3,7,9,16,18,25,28,29,30), times = 3))

We may use

library(dplyr)
dataframe %>% 
    group_by(Condition) %>%
    mutate(Trial = LETTERS[1+ (Time %/%10)]) %>%
    ungroup

We could use case_when:

library(dplyr)

dataframe %>% 
  mutate(Trial = case_when(Time <=10 ~ "A",
                           Time >10 & Time<=20 ~ "B",
                           Time >20 & Time<=30 ~ "C"))

Output:

   Condition  Time Trial
       <dbl> <dbl> <chr>
 1         1     1 A    
 2         1     3 A    
 3         1     7 A    
 4         1     9 A    
 5         1    16 B    
 6         1    18 B    
 7         1    25 C    
 8         1    28 C    
 9         1    29 C    
10         1    30 C    
# ... with 20 more rows
Related