new data frame out of long format depending on condition

Viewed 44

I've got a dataframe in a long form (90 rows for each participant). In this dataframe is one column with reaction times. And I've got another column (a factor with the two levels "match" and "mismatch").

I want to calculate an index that looks something like this: mean RT of the mismatches - mean RT of the matches. I added na.rm=TRUE because there are RTs for every row but not every row has matches or mismatches, some are also NAs.

mean(dato$MMRT [dato$Matcheig == "mismatch"], na.rm=TRUE) - mean(dato$MMRT [dato$Matcheig == "match"], na.rm=TRUE)

How can I get an index over these 90 rows per participant for each of them? I would prefer a new data frame with one line for each participant (VP) and a column with its index.

I tried my best with dplyr but to be honest, I only heard about it yesterday (I'm new here) and maybe someone can tell me if there is an easy solution

datindex <- dato %>%
+   group_by(VP) %>%
+   mean(dato$MMRT [dato$Matcheig == "mismatch"], na.rm=TRUE) - mean(dato$MMRT [dato$Matcheig == "match"], na.rm=TRUE)

This gives the error "argument is not numeric or logical: returning NA" and a 1x1 data frame with NA

Example: dato looks like this (with only 5 rows for each participant now):

VP MMRT Matcheig
1  868  match
1  640  match
1  683  mismatch
1  643  NA
1  904  mismatch
2  705  mismatch
2  634  match
2  819  match
2  700  mismatch
2  765  mismatch

Result should look like this:

VP index
1  39.5
2  -3.2

because the mean RT of the mismatches of participant 1 is 793.5 and of the matches 754

--> 793.5 - 754 = 39.5

and for participant 2: mean RT(mismatches) = 723.3 and mean RT(matches) = 726.5

--> 723.3 - 726.5 = -3.2

1 Answers

1) You should not use $ in dplyr pipes, very rarely they are useful.

2) You should include the calculation inside summarise or mutate functions in dplyr.

library(dplyr)

dato %>%
  group_by(VP) %>%
  summarise(calc = mean(MMRT[Matcheig == "mismatch"], na.rm=TRUE) - 
                   mean(MMRT[Matcheig == "match"], na.rm=TRUE)) 


# A tibble: 2 x 2
#     VP  calc
#  <int> <dbl>
#1     1 39.5 
#2     2 -3.17

The same can also be done using data.table in similar fashion which is useful for large datasets

library(data.table)
setDT(dato)[, (mean(MMRT[Matcheig == "mismatch"], na.rm=TRUE) - 
               mean(MMRT[Matcheig == "match"], na.rm=TRUE)), VP]
Related