因素可以帮助防止R中的某些编程错误:您无法对使用不同级别的因素执行相等性检查,并且在执行大于/小于检查无序因子时会收到警告。
a <- factor(letters[1:3])
b <- factor(letters[1:3], levels=letters[4:1])
a == b
## Error in Ops.factor(a, b) : level sets of factors are different
a < a
## [1] NA NA NA
## Warning message:
## In Ops.factor(a, a) : < not meaningful for factors
然而,与我的预期相反,合并数据帧时不会执行此检查:
ad <- data.frame(x=a, a=as.numeric(a))
bd <- data.frame(x=b, b=as.numeric(b))
merge(ad, bd)
## x a b
## 1 a 1 4
## 2 b 2 3
## 3 c 3 2
这些因素似乎只是强迫角色。
某个可以进行检查的“安全合并”吗?您是否看到默认情况下不进行此项检查的具体原因?
示例(现实使用案例):假设两个空间数据集具有非常相似但不完全相同的细分,例如,communes。数据集指的是稍微不同的时间点,并且一些公社在该时间跨度内合并。每个数据集都有一个“commune ID”列,甚至可能名称相同。虽然此列的语义非常相似,但我不希望(意外地)合并此commune ID列上的数据集。相反,我在“旧”和“新”公社ID之间构建匹配表。如果将commune ID编码为因子,则“安全合并”将对合并操作进行正确性检查,而无需额外(实现)成本和非常少的计算成本。
答案 0 :(得分:1)
merge
的“安全警卫”是by=
参数。您可以准确设置您认为应匹配的列。如果匹配两个因子列,R将使用这些值的标签来匹配它们。所以“a”将与“a”匹配,无论因子的隐藏内部工作如何编码这些值。这就是用户看到的内容,因此它将如何合并。它与数值一样,您可以选择合并具有完全不同范围的列(第一列为1:10,第二列为100:1000)。设置by
值后,R将按照要求进行操作。如果您没有明确设置by
参数,那么R将在两个data.frames中找到所有共享列名并使用它。
很多时候合并时,你并不总是期待比赛。有时您使用all.x
或all.y
专门获取不匹配的记录。在这种情况下,根据不同data.frames的创建方式,人们可能不知道它没有的级别。所以尝试合并它们并不是没有道理的。
所以基本上R在合并期间会处理像字符这样的因素,因为它假设你已经知道两列属于一起。
答案 1 :(得分:0)
好吧,MrFlick给予了很多信任(并道歉):
> attributes(ad$x)
$levels
[1] "a" "b" "c"
$class
[1] "factor"
> attributes(ad$a)
NULL
> attributes(ad$b)
NULL
> adfoo<-merge(ad,bd)
> attributes(adfoo$x)
$levels
[1] "a" "b" "c"
$class
[1] "factor"
事实上,合并后的列$x
是一个因素,尽管只合并了ad
和bd
共有的级别。很久以前,其他列都是通过as.numeric强制执行的。