在R中使用%in%进行子集化

问题描述 投票:2回答:4

出于某种原因,我遇到了一个问题,使用%in%运算符删除单个数据框中没有两个不同时间点值的主题。我的数据框格式很长,属于这种类型:

Subject Group Timepoint word.RT
399     1        t1     979
399     1        t1     818
399     1        t1     761
399     1        t1    1066
399     1        t2     855
399     1        t2    1338
399     1        t2     834
399     1        t2    1018

数据位于简单的.csv文件中。

因为这项研究仍在进行中,并且缺少数据,一些受试者只有t1数据而其他人只有t2数据。为了分配只有t1t2数据的主题,我一直在使用(并在过去成功使用)以下代码:

dat <- dat[dat$Subject[dat$Timepoint=="t1"] %in% 
           dat$Subject[dat$Timepoint=="t2"],]

dat <- dat[dat$Subject[dat$Timepoint=="t2"] %in% 
           dat$Subject[dat$Timepoint=="t1"],]

奇怪的是这适用于某些主题,但不适用于其他主题,我甚至有一个实例,它将适用于一个主题,然后我将关闭R,重新加载一切,再试一次,它将无法工作以前曾为之工作过的一些科目。我确保每个主题的时间点都被编码为t1t2,并且没有像某个随机空间那样奇怪的格式化事件。在使用%in%运算符进行子集化时,是否存在这样的错误?

r
4个回答
3
投票

我鼓励你学习并使用dplyrdata.table来做这种事情。要么运作良好,但最好选择一个开始并熟悉它。他们都有他们的追随者。要么让你的生活变得无比轻松。我在这里展示了两种选择。在这种情况下,也许dplyr看起来稍微简单,但对于其他操作data.table将更简洁:

library(dplyr)
dat %>%
  group_by(Subject) %>%
  filter(all(c('t1','t2') %in% Timepoint))

library(data.table)
setDT(dat)[, both := all(c('t1','t2') %in% Timepoint), by = Subject][both == TRUE]

0
投票

问题似乎是dat$Subject[dat$Timepoint=="t1"] %in% dat$Subject[dat$Timepoint=="t2"]是一个长度为length(dat$Subject[dat$Timepoint=="t1"])的布尔矢量,而不是你需要的长度length(dat$Subject)。这可能会导致一些意外的行为。我建议如下:

subjects_with_both_ts <- dat$Subject[dat$Timepoint=="t1"]
[dat$Subject[dat$Timepoint=="t1"] %in% dat$Subject[dat$Timepoint=="t2"]
dat <- dat[dat$Subject %in% subjects_with_both_ts,]

0
投票

解决这个问题的一种更自然的方法是将数据重新整形为宽格式。但是,您的数据不适合这种情况。您没有唯一标识符(即,没有列的组合唯一标识感兴趣的变量,word.RT)。这不是最佳做法。以下是一种既可以生成唯一标识符又可以解决问题的方法。

library(tidyverse)

d %>% 
  group_by(Timepoint)%>%
  mutate(Timepoint_Key = sequence(n())) %>%
  spread(Timepoint, word.RT) %>% 
  filter(complete.cases(.))

如果你想回到长期追加

  gather(TimePoint,t1, -Subject,-Group, -key) %>%
  rename(word.RT = t1)

0
投票

尝试更换:

dat <- dat[dat$Subject[dat$Timepoint=="t1"] %in% 
           dat$Subject[dat$Timepoint=="t2"],]

有:

subj_of_interest <- unique(with(dat, Subject[which(timepoint=='t2')]))
dat[with(dat,which(Timepoint=='t1' & (Subject %in% subj_of_interest))),]

代码中的部分问题是当你在%in%的LHS上进行子集时,它将返回一个比dat的行数更短的T / F向量。这意味着用于检索结果的T / F向量不会将1-1映射到您期望的结果,并且可能看起来有点奇怪或完全且明显错误,具体取决于您的数据集。

我也建议使用qazxsw poi,因为它会自动排除qazxsw poi,而不使用哪个将返回which()s和NAs结果

© www.soinside.com 2019 - 2024. All rights reserved.