从data.frame中删除列时,我遇到了一个奇怪的行为。最初我有:
> a <- data.frame("a" = c(1,2,3), "abc" = c(3,2,1)); print(a)
a abc
1 1 3
2 2 2
3 3 1
现在,我从data.frame
中删除a$a
> a$a <- NULL; print(a)
abc
1 3
2 2
3 1
正如预期的那样,我的data.frame中只有abc
列。但是当我尝试引用已删除的列a
时,奇怪的部分开始了。
> print(a$a)
[1] 3 2 1
> print(is.null(a$a))
[1] FALSE
看起来R返回a$abc
而不是NULL
的值。
当剩余列名称的开头与已删除列的名称完全匹配时,会发生这种情况。
这是一个错误还是我错过了什么?
答案 0 :(得分:8)
来自帮助。 ?$
name:文字字符串或 名称(可能是引号引用)。对于 提取,这通常是(见 部分地在“环境”下 匹配对象的名称。
这是正常行为,因为名称部分匹配。有关部分匹配的详细信息,请参阅?pmatch。
干杯
答案 1 :(得分:4)
也许值得指出(因为它没有出现在前一个related question),这种部分匹配行为可能是避免使用'$'的理由,除非作为交互式使用R时的方便简写(至少,这是小心使用它的原因。)
如果您知道列的名称而不是位置,则通过dat[,'ind']
选择列;如果您知道位置,则通过dat[,3]
选择列,这通常会更安全,因为您不会发生冲突部分匹配。
答案 2 :(得分:0)
来自R语言定义[第3.4.1节第16-17页] -
https://cran.r-project.org/doc/manuals/r-release/R-lang.pdf
•字符:i中的字符串与x的names属性匹配,并使用生成的整数。对于[[和$部分匹配,如果完全匹配失败,则使用x $ aa将匹配x $ aabb,如果x不包含名为“aa”的组件,则“aabb”是唯一具有前缀“aa”的名称。对于[[,部分匹配可以通过确切的参数来控制,该参数默认为NA,表示允许部分匹配,但应该导致 发生时发出警告。将exact设置为TRUE可防止发生部分匹配,FALSE值允许它并且不发出任何警告。请注意[始终需要完全匹配。字符串“”被特别处理:它表示“没有名字”并且不匹配任何元素(甚至没有名称的那些元素)。请注意,部分匹配仅在提取时使用 而不是在更换时。
答案 3 :(得分:0)
虽然您的确切问题已在评论中得到解答,但避免此行为的替代方法是将您的data.frame
转换为tibble
,这是data.frame
的剥离版本在other things:
library(tibble)
df_t <- as_data_frame(a)
df_t
# A tibble: 3 × 1
abc
<dbl>
1 3
2 2
3 1
> df_t$a
NULL
Warning message:
Unknown column 'a'