Is there a short alternative to as.numeric(as.character(my.factor)) in R?
如果我想在 R 中获取一个因子的数值,我已经厌倦了写 as.numeric(as.character(my.factor))。虽然它有效,但代码的作用并不是不言而喻的,只是感觉转换数字是错误的到字符串并再次返回以对它们进行任何操作。有没有像 factor.values(my.factor) 这样更简单、更不言自明的方式?
建议将其打包到自定义函数中,例如
1
| factor.values = function(x) as.numeric(levels(x))[x] # get the actual values of a factor with numeric labels |
这个解决方案的问题是,如果它要被协作者重现,它必须在脚本之间复制粘贴。我在问是否有一个简短的内置方法可以做到这一点。我知道这是一个非常小的问题,但由于它很常见,而且许多人发现通常提出的解决方案违反直觉,所以我还是提出了它。
问题
Fpr the unitiated,如果你有一个因子并且想要对它进行数值运算,你会遇到很多问题:
1 2 3 4 5 6 7 8 9 10 11 12
| > my.factor = factor(c(1, 1, 2, 5, 8, 13, 21))
> sum(my.factor) # let's try a numeric operation
Error in Summary.factor(1:6, na.rm = FALSE) :
sum not meaningful for factors
> as.numeric(my.factor) # oh, let's make it numeric then.
[1] 1 1 2 3 4 5 6 # argh! levels numbers and not values
> as.character(my.factor) # because the web told me so.
[1]"1" "1" "2" "5" "8" "13""21" # closer...
> as.numeric(as.character(my.factor)) # NOT short or self-explanatory!
[1] 1 1 2 5 8 13 21 # finally we can sum ...
> sum(as.numeric(as.character(my.factor)))
[1] 51 |
- 根据我的经验,只有在数据导入出现问题时才需要这样做。解决方案通常是修复导入步骤。数字信息不应该是一个开始的因素。
-
没错,但方便的函数,如 mapvalues 无缘无故地从数字数据中提取因子。所以我经常发现自己在使用它。
-
只需围绕"丑陋"代码编写一个简单的package函数并完成它。自己动手真的没什么大不了的。
-
你能提供一个mapvalues"无缘无故地用数字数据制作因子"的例子吗?
-
当然,@nicola,我已经用那个例子更新了这个问题。约书亚,请参阅我对以下答案的回复。我仍然认为该解决方案很混乱。我可能对我的 R 代码有不切实际的审美目标。
-
(对我来说)不使用因子更简单,但如果你已经有了它们,这里是 plyr 的替代方法:df.target$x <- with(df.source, setNames(x, id))[as.character(df.target$id)]。这是另一个:m <- merge(df.source, df.target, by="id", sort=FALSE); m[order(m$id),]
-
@JonasLindel?v 我真的不认为这个例子说明了你的观点。你给 mapvalues 一个 factor 并且你得到一个 factor 返回。这完全是意料之中的。"丑陋"来自于错误的数据形式。您允许 id 列成为 factor 是否有原因?
-
@nicola id 是一个因素,因为它是一个不应进行数值运算的分组。因此,这只是一种确保在无意中发生警告/错误的方法,但是我想如果您开箱即用地编写防弹代码,则没有必要:-)但是是的,我现在意识到 mapvalues 当然应该保持 x 作为一个因素 - 在 x 中有一个未被替换的值的情况下很明显。我已从问题中删除了该示例。感谢您指出。
来自 ?factor
To transform a factor ‘f’ to approximately its
original numeric values, ‘as.numeric(levels(f))[f]’ is recommended
and slightly more efficient than ‘as.numeric(as.character(f))’.
- 谢谢(你的)信息。但是在语法方面,它变得更加复杂,尤其是在处理 data.frames 时。比较 as.numeric(as.character(mydf$column)) 和 as.numeric(levels(mydf$column))[mydf$column]
-
然后将复杂的语法放在一个函数中。这就是函数的用途。
-
可能是我太习惯python了,也就是代码其实很漂亮。但我希望有比在我编写的每个脚本中复制/获取的函数更漂亮的东西。好吧,也许我的期望太高了。
-
@JonasLindel?v:您不必在编写的每个脚本中复制/获取该函数。这就是包的用途......或者您可以将其源到附加到您的.Rprofile中的搜索路径的环境中。说"代码实际上很漂亮"是主观的。你觉得漂亮的代码可能对其他人没有吸引力。出于这个原因,我考虑将投票结束为"主要基于意见"(即哪个"漂亮"版本是"最好的漂亮版本"?)。
-
取点。我已将问题更新为是否存在更短、更直观(更少迂回)的解决方案,而不是"漂亮"的解决方案,因为这就是我的意思。答案似乎是"不",我会接受这个答案。将它放在我自己的环境中的问题在于,当您与他人共享脚本时会引发问题。我也用该请求更新了问题。