I have a data set with the following structure:

dat<- data.frame(ID= c("A","A","A", "A", "B", "B", "B", "B"), 
             test= rep(c("pre","post"),4),
             item= c(rep("item1",2), rep("item2",2)),
             answer= c(0,5,4,-3,1,1,5,6))

For each level of ID, test, and item, I want to measure the amount of change and create a categorical variable that identifies the amount as a positive, negative or no change (none).

The result data frame for this example would look like:

res<- data.frame(ID= c("A","A", "B", "B"), 
             item= c(rep(c("item1","item2"),2)),
             diff= c(5, -7, 0,1), 
             change_type=c("positive","negative", "none", "positive"))

1 Answer 1


First of all, I believe the second line in dat should be as follows: test = rep(c("pre", "post"), 4)?

This way, you'll have a following table.

ID test item   answer
A  pre  item1  0
A  post item1  5
A  pre  item2  4
A  post item2 -3
B  pre  item1  1
B  post item1  1
B  pre  item2  5
B  post item2  6

If this is a case, then this little piece of code should help you.

result <- dat %>%
  group_by(ID, item) %>%
  mutate(diff = answer - lag(answer, 1)) %>%
  mutate(change_type = ifelse(answer - lag(answer, 1) > 0, "positive", 
                              ifelse(answer - lag(answer, 1) < 0, "negative", "none"))) %>%
  select(-test, -answer) %>%
  • 1
    $\begingroup$ Thank you and I edited the post fromtest= rep("pre","post",4) to test= rep(c("pre","post"),4) $\endgroup$
    – WabiSabi
    May 4, 2022 at 21:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.