【发布时间】:2017-07-11 17:21:42
【问题描述】:
我试图理解 R 中 subset() 函数和 $ 运算符的使用的怪癖。我将以 R 中的CO2 数据集为例:
我可以跑
sub <- subset(CO2, CO2$Type=="Quebec")
没有错误地到达相同的数据集,就像我要运行一样
sub <- subset(CO2, Type=="Quebec")
但是,我发现情况并非总是如此。
有时在subset() 函数中包含$ 会产生以下错误
$ 运算符对原子向量无效
是什么触发了“$ 运算符对原子向量无效”错误?
为什么在某些情况下允许使用$(如上面的二氧化碳示例)但在其他情况下不允许使用?(当我通过read.csv() 引入自己的数据时,我特别沮丧,有时我会收到错误消息当尝试使用 $ 进行子集化时,有时我没有任何可辨别的模式)
谢谢!
根据下面的 cmets,我正在尝试发布可重现的示例。
下面是触发错误的情况:
Moose<-structure(list(Moose = 1:25, Tagging_Loc = structure(c(1L, 1L,
2L, 1L, 1L, 2L, 2L, 2L, 2L, 1L, 2L, 1L, 2L, 2L, 1L, 1L, 2L, 1L,
2L, 1L, 1L, 2L, 1L, 2L, 2L), .Label = c("A", "B"), class = "factor"),
Gender = structure(c(2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 1L,
2L, 1L, 1L, 1L, 2L, 1L, 2L, 2L, 1L, 2L, 2L, 1L, 1L, 2L, 1L,
2L), .Label = c("F", "M"), class = "factor"), Age = c(20L,
23L, 14L, 15L, 10L, 9L, 5L, 10L, 19L, 22L, 21L, 21L, 7L,
16L, 19L, 9L, 23L, 5L, 9L, 10L, 16L, 8L, 13L, 14L, 6L), Weight = c(1366L,
1006L, 888L, 1359L, 899L, 635L, 400L, 1000L, 1012L, 1480L,
1001L, 1100L, 482L, 1414L, 971L, 725L, 1400L, 416L, 790L,
970L, 921L, 560L, 1103L, 904L, 669L), Distance = c(250.5,
410.239, 457.6402591, 245.8523, 430.9975, 308.8673107, 212.5212497,
414.2093545, 439.6581, 215.6491489, 464.2384, 425.4256828,
233.5635555, 207.98, 453.7098751, 390.0506365, 235.5212497,
207.368, 427.5084899, 443.0452824, 459.8999274, 274.6856592,
350.5661674, 456.9600032, 330.146)), .Names = c("Moose",
"Tagging_Loc", "Gender", "Age", "Weight", "Distance"), class = "data.frame", row.names = c(NA,
-25L))
sub_Moose<-subset(Moose, Moose$Tagging_Loc=="A")
sub_Moose<-subset(Moose, Tagging_Loc=="A")'
但如果我只更改数据集的名称,subset() 的两个版本都可以正常运行 - 没有错误:
mOose<-structure(list(Moose = 1:25, Tagging_Loc = structure(c(1L, 1L,
2L, 1L, 1L, 2L, 2L, 2L, 2L, 1L, 2L, 1L, 2L, 2L, 1L, 1L, 2L, 1L,
2L, 1L, 1L, 2L, 1L, 2L, 2L), .Label = c("A", "B"), class = "factor"),
Gender = structure(c(2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 1L,
2L, 1L, 1L, 1L, 2L, 1L, 2L, 2L, 1L, 2L, 2L, 1L, 1L, 2L, 1L,
2L), .Label = c("F", "M"), class = "factor"), Age = c(20L,
23L, 14L, 15L, 10L, 9L, 5L, 10L, 19L, 22L, 21L, 21L, 7L,
16L, 19L, 9L, 23L, 5L, 9L, 10L, 16L, 8L, 13L, 14L, 6L), Weight = c(1366L,
1006L, 888L, 1359L, 899L, 635L, 400L, 1000L, 1012L, 1480L,
1001L, 1100L, 482L, 1414L, 971L, 725L, 1400L, 416L, 790L,
970L, 921L, 560L, 1103L, 904L, 669L), Distance = c(250.5,
410.239, 457.6402591, 245.8523, 430.9975, 308.8673107, 212.5212497,
414.2093545, 439.6581, 215.6491489, 464.2384, 425.4256828,
233.5635555, 207.98, 453.7098751, 390.0506365, 235.5212497,
207.368, 427.5084899, 443.0452824, 459.8999274, 274.6856592,
350.5661674, 456.9600032, 330.146)), .Names = c("Moose",
"Tagging_Loc", "Gender", "Age", "Weight", "Distance"), class = "data.frame", row.names = c(NA,
-25L))
sub_Moose<-subset(mOose, mOose$Tagging_Loc=="A")
sub_Moose<-subset(mOose, Tagging_Loc=="A")
【问题讨论】:
-
能否提供一个可重现的例子?
-
您使用
subset()的主要原因是您不必使用$。如果感兴趣的变量来自第一个参数中的 data.frame,您应该不使用$。当您拥有与 data.frame 同名的列时,您可能会收到错误消息。但它也可能由于其他原因而发生。你真的应该在寻求帮助时提供reproducible example -
还要注意使用子集。正如它在帮助文件底部附近所说的那样,
?subset,“这是一个旨在以交互方式使用的便利函数。对于编程,最好使用标准子集函数,例如 [,特别是参数的非标准评估子集可能会产生意想不到的后果。” -
抱歉,这是我的第一篇文章。 CO2 是 R 中可用的数据集。为什么我的示例不被认为是可重现的?另外,我知道
$不是subset()所必需的,但我试图确定为什么有时会触发原子向量错误,但有时不会触发。 -
@lmo 我从来没有理解过这个警告。这只是一个通用的 NSE 警告。这同样适用于任何
dplyr功能,但人们一直在使用这些功能。如果子集按照应有的方式使用,则很好。没有理由害怕它。