Reputation: 361
In my previous question, I needed to create a new column according to values in another column. In that question, values in expected_result
is only updated when there is a CS+
in stimulus
column. What I am trying to do now is to only update the value after there is a new CS+
. Expected results are as shown in figure 1. For instance, in the second CS+
, the value is still 30, it is only updated to 36 in the next trial.
Figure 1
Example data
structure(list(subject = c("subject1", "subject1", "subject1",
"subject1", "subject1", "subject1", "subject1", "subject1", "subject1",
"subject2", "subject2", "subject2", "subject2", "subject2", "subject2",
"subject2", "subject2", "subject2"), stimulus = c("CS-", "CS-",
"CS+", "CS-", "S8", "S7", "S2", "CS+", "CS+", "CS-", "CS-", "CS+",
"S4", "S9", "S7", "CS+", "CS+", "S8"), Per_size = c(60L, 70L,
30L, 85L, 62L, 56L, 42L, 36L, 34L, 24L, 21L, 70L, 65L, 31L, 35L,
79L, 79L, 34L), new_expect = c(30, 30, 30, 30, 30, 30, 30, 30,
36, 36, 36, 36, 70, 70, 70, 70, 79, 79)), row.names = c(NA, -18L
), class = c("data.table", "data.frame"))
Solution provided by @akrun for the previous question where values are updated on the CS+
trial.
df1[stimulus == 'CS+', New := Per_size]
df1[, New := nafill(nafill(New, type = 'locf'), type = 'nocb'), subject]
Upvotes: 1
Views: 172
Reputation: 887911
Based on the expected showed, it is breaking the grouping. We could do
library(dplyr)
library(tidyr)
df1 %>%
group_by(subject) %>%
mutate(New = lag(case_when(stimulus == 'CS+' ~ Per_size))) %>%
ungroup %>%
fill(New, .direction = 'downup')
-ouptut
# A tibble: 18 x 5
subject stimulus Per_size new_expect New
<chr> <chr> <int> <dbl> <int>
1 subject1 CS- 60 30 30
2 subject1 CS- 70 30 30
3 subject1 CS+ 30 30 30
4 subject1 CS- 85 30 30
5 subject1 S8 62 30 30
6 subject1 S7 56 30 30
7 subject1 S2 42 30 30
8 subject1 CS+ 36 30 30
9 subject1 CS+ 34 36 36
10 subject2 CS- 24 36 36
11 subject2 CS- 21 36 36
12 subject2 CS+ 70 36 36
13 subject2 S4 65 70 70
14 subject2 S9 31 70 70
15 subject2 S7 35 70 70
16 subject2 CS+ 79 70 70
17 subject2 CS+ 79 79 79
18 subject2 S8 34 79 79
Or using data.table
library(data.table)
library(zoo)
df1[, New := shift(fcase(stimulus == 'CS+', Per_size)),
subject][, New := nafill(nafill(New, type = 'locf'), type = 'nocb')]
-ouptut
df1
subject stimulus Per_size new_expect New
1: subject1 CS- 60 30 30
2: subject1 CS- 70 30 30
3: subject1 CS+ 30 30 30
4: subject1 CS- 85 30 30
5: subject1 S8 62 30 30
6: subject1 S7 56 30 30
7: subject1 S2 42 30 30
8: subject1 CS+ 36 30 30
9: subject1 CS+ 34 36 36
10: subject2 CS- 24 36 36
11: subject2 CS- 21 36 36
12: subject2 CS+ 70 36 36
13: subject2 S4 65 70 70
14: subject2 S9 31 70 70
15: subject2 S7 35 70 70
16: subject2 CS+ 79 70 70
17: subject2 CS+ 79 79 79
18: subject2 S8 34 79 79
Upvotes: 1