在subset函数中使用多个条件和逻辑运算符

28

如果我想在R中选择数据子集,我可以使用subset函数。我想基于符合某些条件的数据进行分析,例如某个变量是1、2或3。我尝试了

myNewDataFrame <- subset(bigfive, subset = (bigfive$bf11==(1||2||3)))
它总是只选择符合第一个条件的值,这里是1。我的假设是它会从1开始,如果评估为“false”,它就会转到2,然后到3,如果没有匹配,那么在==之后的语句就是“false”,如果其中一个匹配,则为“true”。 我使用了正确的方法得到结果。
 newDataFrame <- subset(bigfive, subset = (bigfive$bf11==c(1,2,3)))

但我希望能够通过逻辑运算符选择数据,那么:为什么第一个方法不起作用?


请查看“逻辑帮助页面”。||表单从左到右进行操作,只检查向量中的第一个元素。在这些情况下,%in%也是一个有用的运算符。搜索 [r] %in% 可以很有启发性。 - Chase
2
@Chase 这里 ||| 是无用的:1||2||31|2|3 都会被计算为 TRUE,因此子集只包括那些 bf11 为 TRUE(或者计算结果为 TRUE 的情况)。在这里使用 %in% 更加有帮助。 - Gavin Simpson
@Gavin - 感谢你帮我完成那句话 - 我得去参加另一个会议了。 - Chase
你所说的“得到了正确的结果”可能会忽略一些bf11确实为1、2或3的情况。正如Gavin Simpson所说,%in%是最好的选择。 - Henry
2个回答

41

这里正确的运算符是%in%。这是一个使用虚拟数据的示例:

set.seed(1)
dat <- data.frame(bf11 = sample(4, 10, replace = TRUE),
                  foo = runif(10))

提供:

> head(dat)
  bf11       foo
1    2 0.2059746
2    2 0.1765568
3    3 0.6870228
4    4 0.3841037
5    1 0.7698414
6    4 0.4976992

使用%in%操作符,选取dat数据集中bf11等于1,2,3中任意一个的子集:

> subset(dat, subset = bf11 %in% c(1,2,3))
   bf11       foo
1     2 0.2059746
2     2 0.1765568
3     3 0.6870228
5     1 0.7698414
8     3 0.9919061
9     3 0.3800352
10    1 0.7774452

至于为什么您原来的代码没有起作用,可以将其分解以查看问题所在。 查看 1 || 2 || 3 的求值结果:

> 1 || 2 || 3
[1] TRUE

如果你使用 | 替代使用 &&,你将得到相同的结果。因此,subset() 函数仅会返回 bf11TRUE(或者等价于 TRUE 的值)的行。

你本可以这样写:

subset(dat, subset = bf11 == 1 | bf11 == 2 | bf11 == 3)

这与我早先使用的 subset() 函数调用得到了相同的结果。关键是您需要一系列单一的比较,而不是一系列选项之间的比较。但是如您所见,在这种情况下,%in% 更加有用且简洁。请注意,我必须使用 | ,因为我想逐个将 bf11 的每个元素与 123 进行比较。比较:

> with(dat, bf11 == 1 || bf11 == 2)
[1] TRUE
> with(dat, bf11 == 1 | bf11 == 2)
 [1]  TRUE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE

1
我该如何查找关于"%in%"的帮助页面?我使用了 ?%in%,但它没有起作用。 - kuki
3
请引用运算符:类似于 ?"%in%" - Gavin Simpson

11

就您的示例而言,我相信以下代码应该有效:

myNewDataFrame <- subset(bigfive, subset = bf11 == 1 | bf11 == 2 | bf11 == 3)

查看?subset中的示例以获取更多信息。仅为演示,一个更复杂的逻辑子集将是:

data(airquality)
dat <- subset(airquality, subset = (Temp > 80 & Month > 5) | Ozone < 40)

正如Chase指出的那样,%in%在你的例子中会更有效率:

myNewDataFrame <- subset(bigfive, subset = bf11 %in% c(1, 2, 3))

正如Chase指出的那样,确保你理解|||之间的差异。要查看运算符的帮助页面,请使用引号引用运算符的方式?'||'


?'||'在R中运行良好,?"||"也是如此。关键是这些运算符和其他一些结构需要被“引用”。因此我从你的答案中删除了这些句子。 - Gavin Simpson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接