在R中使用%in

时间:2017-12-12 20:52:08

标签: r

出于某种原因,我遇到了一个问题,使用%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%运算符进行子集化时,是否存在这样的错误?

4 个答案:

答案 0 :(得分: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]

答案 1 :(得分: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映射到您期望的结果,并且可能看起来有点奇怪或完全且明显错误,具体取决于您的数据集。

我还建议使用which(),因为它会自动排除NAs,而不使用哪个会返回TRUENA结果

答案 2 :(得分: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,]

答案 3 :(得分: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)