一列因子上的 sum(.) 返回不正确的结果

4
我在这里遇到了奇怪的问题。我正在使用data.table来完成一个非常常规的任务,但有一些我无法解释的问题。我已经找到了解决问题的方法,但我认为了解这里出了什么问题仍然很重要。
这段代码会将数据导入工作区:
library(XML)
library(data.table)
theurl <- "http://goo.gl/hOKW3a"
tables <- readHTMLTable(theurl)
new.Res <- data.table(tables[[2]][4:5][-(1:2),])
suppressWarnings(names(new.Res) <- c("Party","Cases"))

这里有两列,PartyCases。它们默认的类别都是factor,但是Cases应该是numeric。最终,我只需要每个PartyCases总和。所以像这样做应该可以:
new.Res[,sum(Cases), by=Party]

但这并不能得到正确的答案。我认为如果将Cases的类从factor更改为numeric,它就会起作用。所以我尝试了以下操作:

new.Res[,Cases := as.numeric(Cases)]
new.Res[,sum(Cases), by=Party]

但是我得到了相同的错误答案。我意识到问题发生在将 Cases 类从 factor 更改为 numeric 上。因此,我尝试了一种不同的方法,它起作用了:

步骤1:重新初始化数据:

theurl <- "http://goo.gl/hOKW3a"
tables <- readHTMLTable(theurl)
new.Res <- data.table(tables[[2]][4:5][-(1:2),])
suppressWarnings(names(new.Res) <- c("Party","Cases"))

步骤2:使用不同的方法将类别从因子更改为数值型

new.Res[,Cases := strtoi(Cases)]
new.Res[,sum(Cases), by=Party]

这个方法可以正常工作!然而,我不确定前两种方法出了什么问题。我漏掉了什么吗?

1个回答

8
factor类型转换为numericinteger的正确方式是通过character类型进行转换。这是因为在内部,factor是一个整数索引(指向一个levels向量)。 当您告诉R将其转换为numeric时,它只会转换底层索引,而不会尝试转换级别标签。
简短回答:执行Cases:=as.numeric(as.character(Cases))编辑:另外,?factor帮助页面建议使用as.numeric(levels(Cases))[Cases]更有效率。感谢评论中的@Gsee提供的提示。

2
每个人都会被@Shambo这一招击中 :-) 这是成长的必经之路。 - ilir
3
这似乎是最常见的方法,但请注意 ?factor 中提到:“为了将因子 f 转换为其原始数值的近似值,建议使用 as.numeric(levels(f))[f],这比 as.numeric(as.character(f)) 稍微更有效率一些。” - GSee
1
我记得读过类似的内容,但通常的方法更容易记住。 - ilir

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