按因子列安全合并数据框

问题描述 投票:0回答:2

因子可以帮助防止 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

这些因素似乎只是强加给角色的。

是否有“安全合并”可以进行检查?您是否看到默认情况下不执行此检查的具体原因?

示例(现实生活中的用例):假设两个空间数据集具有非常相似但不相同的细分,例如在公社中。这些数据集所指的时间点略有不同,并且一些公社在该时间跨度内已经合并。每个数据集都有一个“公社 ID”列,甚至可能名称相同。虽然此列的语义非常相似,但我不想(意外地)合并此公社 ID 列上的数据集。相反,我在“旧”和“新”公社 ID 之间构建了一个匹配表。如果公社 ID 被编码为因子,则“安全合并”将为合并操作提供正确性检查,而无需额外(实现)成本和很少的计算成本。

r merge
2个回答
2
投票

merge
的“安全卫士”就是
by=
参数。您可以准确设置您认为应该匹配的列。如果匹配两个因子列,R 将使用这些值的标签来匹配它们。因此,“a”将与“a”匹配,无论因子的隐藏内部工作如何编码这些值。这就是用户看到的内容,因此这就是合并的方式。就像数值一样,您可以选择合并具有完全不同范围的列(第一列有 1:10,第二列有 100:1000)。设置
by
值后,R 将执行其要求的操作。如果您没有显式设置
by
参数,那么 R 将找到两个 data.frame 中的所有共享列名称并使用它。

很多时候合并时,您并不总是期望匹配。有时您会使用

all.x
all.y
来专门获取不匹配的记录。在这种情况下,根据不同 data.frames 的创建方式,人们可能不知道它没有的级别。所以尝试合并它们并不是没有道理的。

所以基本上 R 在合并过程中处理诸如字符之类的因素,因为它假设您已经知道两列属于在一起。


0
投票

好吧,非常感谢(并向)Flick 先生表示歉意:

> 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 进行了强制。

© www.soinside.com 2019 - 2024. All rights reserved.