R:每次尝试用因子索引时都会抛出一个错误?

时间:2014-09-26 13:13:23

标签: r indexing

我不知道是否有其他人认为R中的因素非常奇怪并且应该表现得不同,但无论如何,这是问题所在:

问题

> a = matrix(rnorm(12), nrow=3, dimnames=list(LETTERS[5:7],LETTERS[1:4]))
> b = c("B","C")

> a[,b]
       B          C
E -1.1886578  2.6433882
F -0.9113276  0.8333795
G  1.1922121 -1.9239478

如果我使用a索引b,一切都按预期工作。但是,如果b是一个因素,则其整数值用于索引:

> a[,as.factor(b)]
       A          B
E  0.4137923 -1.1886578
F -0.4302323 -0.9113276
G  1.2566591  1.1922121

这是我遇到的无数问题的根源,特别是因为character经常自动转换为factor s,例如将它们放入data.frame

如果这种转化发生一次并且您没有想到它,那么您就有难以追踪的错误。

可能吗?溶液

全球设置stringsAsFactors=F可能是一种糟糕的方法,因为它可能会破坏现有代码。

相反,我每次尝试使用因子索引任何内容时,我都希望R抛出一个错误。我的想法是在我的~/.Rprofile中添加类似下面的代码:

`[` = function(X, ...) {
    if (any(is.factor(...)))
        stop("Indexing with factor")
    else
        .Primitive("[")(X, ...)
}

以上不起作用。我似乎无法找到一个好的解决方案,除了用因子索引时,不会以任何方式中断[

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

您可以轻松地为data.frames执行此操作,因为存在现有的S3方法:

trace("[.data.frame", quote(if (is.factor(j)) warning("Indexing with factor")))
#you could overwrite the method instead of using trace

a = matrix(rnorm(12), nrow=3, dimnames=list(LETTERS[5:7],LETTERS[1:4]))
b = c("B","C")

as.data.frame(a)[,b]
#Tracing `[.data.frame`(as.data.frame(a), , b) on entry 
#           B          C
#E  0.2539326  1.3292468
#F -0.4088534 -0.7554019
#G -1.2535690  0.3149922
as.data.frame(a)[,factor(b)]
#Tracing `[.data.frame`(as.data.frame(a), , factor(b)) on entry 
#           A          B
#E -0.6147412  0.2539326
#F -0.6899518 -0.4088534
#G  1.3720187 -1.2535690
#Warning message:
#  In eval(expr, envir, enclos) : Indexing with factor

untrace("[.data.frame")

您需要对[<-.data.frame执行相同操作。

但是,我不能提供矩阵子集的解决方案,因为它是由原语处理的,我不认为你可以/应该定义一个方法。就个人而言,我很少用字符对矩阵进行子集化。

答案 1 :(得分:0)

如果b是一个因素,只需将as.character()包裹起来。

a[,as.character(factor(b))]
           B        C
E  2.0451415 0.477410
F -0.4739111 1.616437
G -0.2422863 1.791818

这些数字与你的不同,因为你没有给我们一个可重复的例子。您可以使用set.seed()使其在将来重现。