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

Sha*_*bho 4 r data.table

我在这里遇到了一个奇怪的问题.我正在使用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"))
Run Code Online (Sandbox Code Playgroud)

这里有两列,PartyCases.两者都有默认类factor.虽然,Cases应该是numeric.最终,我只想要Cases每个的总和Party.所以像这样的东西应该工作:

new.Res[,sum(Cases), by=Party]
Run Code Online (Sandbox Code Playgroud)

但这并没有给出正确的答案.我想,如果我改变类的它会工作Cases,从factornumeric.所以我尝试了以下方法:

new.Res[,Cases := as.numeric(Cases)]
new.Res[,sum(Cases), by=Party]
Run Code Online (Sandbox Code Playgroud)

但我得到了同样错误的答案.我意识到这个问题是在改变类的发生Cases,从factornumeric.所以我尝试了一种不同的方法,它起作用了:

第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"))
Run Code Online (Sandbox Code Playgroud)

第2步:使用不同的方法将类更改factornumeric:

new.Res[,Cases := strtoi(Cases)]
new.Res[,sum(Cases), by=Party]
Run Code Online (Sandbox Code Playgroud)

这很好用!但是,我不确定前两种方法有什么问题.我错过了什么?

ili*_*lir 7

转换factornumericinteger将要通过的正确方法character.这是因为在内部,因子是整数索引(指向levels量).当你告诉R将其转换为它时,numeric它只会转换基础索引,而不是尝试转换级别标签.

简答:做Cases:=as.numeric(as.character(Cases)).

编辑:或者,?factor帮助页面建议as.numeric(levels(Cases))[Cases]更有效.h/t @Gsee在评论中.

  • 这似乎是最常见的方式,但请注意`?factor`表示"要将因子`f`转换为大约其原始数值,建议使用`as.numeric(levels(f))[f]`比`as.numeric(as.character(f))`更有效率." (3认同)
  • 每个人都喜欢那个@Shambo :-) 这是一种通过仪式。 (2认同)