Reputation: 47
I have a dataset that looks like this:
I want to do a d' prime analysis. To do that, I need to have a data frame that tells me how many times the subject said "yes" to a target (hit), "no" to a target (miss), "yes" to a foil (false alarm), and "no" to a foil (correctly rejected). I need to do that but have different rows per condition (A, B, C).
How can I do that in R using tidyverse?
You can recreate a small portion of my data with this code:
structure(list(id = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1), condition = c("A", "A", "A", "A", "A", "A", "B",
"B", "B", "B", "B", "B", "C", "C", "C", "C", "C", "C"), ft = c("foil",
"target", "target", "target", "foil", "foil", "target", "foil",
"target", "target", "foil", "foil", "foil", "target", "target",
"foil", "target", "foil"), response = c("no", "yes", "yes", "yes",
"yes", "no", "yes", "no", "yes", "yes", "no", "no", "no", "no",
"yes", "no", "no", "no"), noise_signal = c("corr_rej", "hit",
"hit", "hit", "false_a", "corr_rej", "hit", "corr_rej", "hit",
"hit", "corr_rej", "corr_rej", "corr_rej", "miss", "hit", "corr_rej",
"miss", "corr_rej")), row.names = c(NA, -18L), class = c("tbl_df",
"tbl", "data.frame"))
I want the final data frame to look like this:
Upvotes: 0
Views: 48
Reputation: 887213
With data.table
library(data.table)
dcast(setDT(df), condition ~ noise_signal, length)
# condition corr_rej false_a hit miss
#1: A 2 1 3 0
#2: B 3 0 3 0
#3: C 3 0 1 2
Or using base R
table(df[c('condition', 'noise_signal')])
Upvotes: 0
Reputation: 14764
I agree that best way would be by pivoting since you already have the information; however, you could also summarise it as:
library(dplyr)
df %>%
group_by(id, condition) %>%
summarise(hit = sum(response[ft == 'target'] == 'yes'),
miss = sum(response[ft == 'target'] == 'no'),
corr_rej = sum(response[ft == 'foil'] == 'no'),
false_a = sum(response[ft == 'foil'] == 'yes')
)
Output:
# A tibble: 3 x 6
# Groups: id [1]
id condition hit miss corr_rej false_a
<dbl> <chr> <int> <int> <int> <int>
1 1 A 3 0 2 1
2 1 B 3 0 3 0
3 1 C 1 2 3 0
Upvotes: 0
Reputation: 3953
Sum up the number of events by signal category and condition, then pivot the data frame so that each category is in its own column:
dat %>%
group_by(condition, noise_signal) %>%
summarize(n = n()) %>%
pivot_wider(id_cols = condition,
names_from = noise_signal,
values_from = n,
values_fill = list(n = 0))
output:
# A tibble: 3 x 5
# Groups: condition [3]
condition corr_rej false_a hit miss
<chr> <int> <int> <int> <int>
1 A 2 1 3 0
2 B 3 0 3 0
3 C 3 0 1 2
Upvotes: 3