如何比较具有不同水平的两个因素?

4

有没有可能比较两个长度相同但不同级别的因素?例如,如果我们有这两个因素变量:

A <- factor(1:5)

str(A)
 Factor w/ 5 levels "1","2","3","4",..: 1 2 3 4 5

B <- factor(c(1:3,6,6))

str(B)
 Factor w/ 4 levels "1","2","3","6": 1 2 3 4 4

如果我尝试使用例如 == 运算符进行比较:

mean(A == B)

我遇到了以下错误:

Error in Ops.factor(A, B) : level sets of factors are different

这是因为A和B的水平集不同导致的。

1
请你解释一下“比较两个因子”是什么意思。我不太清楚。 - user2100721
1
@user2100721 我猜他们想知道重叠的比例。以我的帖子为例,重叠部分是 3 个,总共有 5 个,所以 3/5 = 0.6。请注意,TRUE / FALSE 会隐式转换为 1/0,即:TRUE + TRUE = 2 - zx8754
1
@zx8754 谢谢。我明白了你的意思。 - user2100721
@zx8754 抱歉打扰了,我之前忘记用 factor 包装了。使用 microbenchmark 测试后,你的解决方案快了近两倍,这有点令人惊讶。 - akrun
@zx8754 我已经在你的答案中添加了该选项,希望你不介意。 - akrun
1
@zx8754 我根本不关心声望 :-) - akrun
2个回答

11

转换为字符后再进行比较:

# data
A <- factor(1:5)
B <- factor(c(1:3,6,6))

str(A)
# Factor w/ 5 levels "1","2","3","4",..: 1 2 3 4 5
str(B)
# Factor w/ 4 levels "1","2","3","6": 1 2 3 4 4

mean(A == B)

Error in Ops.factor(A, B) : level sets of factors are different

错误:Ops.factor(A, B) 中因子的级别集不同。
mean(as.character(A) == as.character(B))
# [1] 0.6

或者另一种方法是

mean(levels(A)[A] == levels(B)[B])

在一个1e8的数据集上,它的速度慢了2倍。


根据你对“比较”的具体含义,你还可以查看all.equal - David_B
@David_B 我不确定在这种情况下如何使用 all.equal - zx8754

1
将其转换为字符,就像@zx8754的答案中所述,是解决这个问题最简单的方法,也可能是你几乎总是想使用的方法。另一个选择是纠正这2个变量,使它们具有相同的级别。如果您希望出于某种原因将这些变量保留为因子,并且不想在代码中重复调用as.character,则可以这样做。
A <- factor(1:5)
B <- factor(c(1:3,6,6))

mean(A == B)
Error in Ops.factor(A, B) : level sets of factors are different

我们可以将两个因子的级别取并集,以获得任一因子中的所有级别,然后使用该并集重新创建因子作为级别。现在,尽管这两个因子具有不同的值,但它们之间的级别是相同的,您可以进行比较。
C = factor(A, levels = union(levels(A), levels(B)))
D = factor(B, levels = union(levels(A), levels(B)))

mean(C==D)
[1] 0.6

正如您所看到的,这些值并没有改变,但是它们的级别现在是相同的。
C
[1] 1 2 3 4 5
Levels: 1 2 3 4 5 6

D
[1] 1 2 3 6 6
Levels: 1 2 3 4 5 6

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