如何在R语言中对同一Item下的多行数据进行筛选
筛选符合特定区域观测条件的Region 3反应时数据
我有一组被试作答数据,每个被试的每个Item对应3行记录,分别对应Item的3个不同Region。Observation字段表示被试是否注视该区域(0=未注视,1=注视)。需要筛选出满足以下所有条件的Region 3的RT数据:
- Region 1的Observation为1
- Region 2的Observation为0
- Region 3的Observation为1
比如示例数据里,Item 1的Region 3不满足条件(Observation为0),不会被纳入;Item 2的Region 3符合所有条件,会被保留。
之前尝试跨行筛选失败:能标记各区域的观测状态,但提取Region 3数据后无法关联同一Item下其他区域的状态,导致没有有效结果。试过按Item分组,但不知道后续操作。
示例数据
| Participant | Item | Region | Observation | RT |
|---|---|---|---|---|
| p1 | Item 1 | Region 1 | 1 | 3300 |
| p1 | Item 1 | Region 2 | 0 | NA |
| p1 | Item 1 | Region 3 | 0 | NA |
| p1 | Item 2 | Region 1 | 1 | 5000 |
| p1 | Item 2 | Region 2 | 0 | NA |
| p1 | Item 2 | Region 3 | 1 | 7000 |
R数据结构
structure(list(Participant = c("p1", "p1", "p1", "p1", "p1", "p1"), Item = c("Item 1", "Item 1", "Item 1", "Item 2", "Item 2", "Item 2"), Region = c("Region 1", "Region 2", "Region 3", "Region 1", "Region 2", "Region 3"), Observation = c(1, 0, 0, 1, 0, 1), RT = c(3300L, NA, NA, 5000L, NA, 7000L)), class = "data.frame", row.names = c(NA, -6L))
解决方案
方法1:分组筛选(dplyr)
按Participant + Item分组,在组内验证三个区域的观测条件,直接筛选符合要求的Region 3记录:
library(dplyr) # 加载数据 df <- structure(list(Participant = c("p1", "p1", "p1", "p1", "p1", "p1"), Item = c("Item 1", "Item 1", "Item 1", "Item 2", "Item 2", "Item 2"), Region = c("Region 1", "Region 2", "Region 3", "Region 1", "Region 2", "Region 3"), Observation = c(1, 0, 0, 1, 0, 1), RT = c(3300L, NA, NA, 5000L, NA, 7000L)), class = "data.frame", row.names = c(NA, -6L)) # 筛选符合条件的Region 3数据 filtered_df <- df %>% group_by(Participant, Item) %>% filter( any(Region == "Region 1" & Observation == 1), any(Region == "Region 2" & Observation == 0), Region == "Region 3" & Observation == 1 ) %>% ungroup() # 输出结果 print(filtered_df)
运行结果:
# A tibble: 1 × 5 Participant Item Region Observation RT <chr> <chr> <chr> <dbl> <int> 1 p1 Item 2 Region 3 1 7000
方法2:宽表转换筛选(tidyr + dplyr)
先将长表转为宽表,把每个Item的三个区域数据合并到一行,再筛选条件,最后提取需要的Region 3数据:
library(tidyr) library(dplyr) df <- structure(list(Participant = c("p1", "p1", "p1", "p1", "p1", "p1"), Item = c("Item 1", "Item 1", "Item 1", "Item 2", "Item 2", "Item 2"), Region = c("Region 1", "Region 2", "Region 3", "Region 1", "Region 2", "Region 3"), Observation = c(1, 0, 0, 1, 0, 1), RT = c(3300L, NA, NA, 5000L, NA, 7000L)), class = "data.frame", row.names = c(NA, -6L)) # 转宽表 wide_df <- df %>% pivot_wider( id_cols = c(Participant, Item), names_from = Region, values_from = c(Observation, RT), names_sep = "_" ) # 筛选条件并提取数据 filtered_result <- wide_df %>% filter( Observation_Region 1 == 1, Observation_Region 2 == 0, Observation_Region 3 == 1 ) %>% select(Participant, Item, RT_Region 3) %>% # 可选:转回长表格式 rename(RT = RT_Region 3) %>% mutate(Region = "Region 3", Observation = 1) %>% select(Participant, Item, Region, Observation, RT) print(filtered_result)
运行结果和方法1一致。
内容的提问来源于stack exchange,提问作者user20792955
相关产品推荐
相关产品推荐

