我想使用下面的代码使用plyr按类别计算最常见的因子级别。数据框b
显示请求的结果。为什么c$mlevels
只有值“numeric”?
require(plyr)
set.seed(0)
a <- data.frame(cat=round(runif(100, 1, 3)),
levels=factor(round(runif(100, 1, 10))))
mode <- function(x) names(table(x))[which.max(table(x))]
b <- data.frame(cat=1:3,
mlevels=c(mode(a$levels[a$cat==1]),
mode(a$levels[a$cat==2]),
mode(a$levels[a$cat==3])))
c <- ddply(a, .(cat), summarise,
mlevels=mode(levels))
答案 0 :(得分:5)
使用summarise
时,plyr
似乎在base
中检查功能之前“看不到”在全局环境中声明的函数:
我们可以使用Hadley方便的pryr
包检查这个。您可以通过以下命令安装它:
library(devtools)
install_github("pryr")
require(pryr)
require(plyr)
c <- ddply(a, .(cat), summarise, print(where("mode")))
# <environment: namespace:base>
# <environment: namespace:base>
# <environment: namespace:base>
基本上,它不会读取/知道/看到您的 mode
功能。有两个替代品。第一个是@AnandaMahto建议的,我会做同样的事情并建议你坚持下去。另一种方法是不使用summarise
并使用function(.)
调用它,以便“看到”全局环境中的mode
函数。
c <- ddply(a, .(cat), function(x) mode(x$levels))
# cat V1
# 1 1 6
# 2 2 5
# 3 3 9
为什么这样做?
c <- ddply(a, .(cat), function(x) print(where("mode")))
# <environment: R_GlobalEnv>
# <environment: R_GlobalEnv>
# <environment: R_GlobalEnv>
因为如上所述,它会读取位于global environment
。
> mode # your function
# function(x)
# names(table(x))[which.max(table(x))]
> environment(mode) # where it sits
# <environment: R_GlobalEnv>
而不是:
> base::mode # base's mode function
# function (x)
# {
# some lines of code to compute mode
# }
# <bytecode: 0x7fa2f2bff878>
# <environment: namespace:base>
Here's an awesome wiki来自哈德利的environments
,如果您有兴趣进一步阅读/探索。
答案 1 :(得分:2)
您在示例中几乎只使用了现有的函数名称:levels
,cat
和mode
。通常,这不会产生太多问题 - 例如,调用data.frame“df”不会破坏R的df()
函数。但它几乎总会导致更模糊或令人困惑的代码,并且在这个的情况下,它使事情“破裂”。 Arun的回答是伟大的工作,显示原因。
您可以通过重命名“模式”功能轻松解决问题。在下面的示例中,除了重命名之外,我还简化了一点,它可以按预期工作。
Mode <- function(x) names(which.max(table(x)))
ddply(a, .(cat), summarise,
mlevels=Mode(levels))
# cat mlevels
# 1 1 6
# 2 2 5
# 3 3 9
当然,有一个非常麻烦的解决方法:使用get
并指定搜索功能的位置。
> mode <- function(x) names(table(x))[which.max(table(x))]
> ddply(a, .(cat), summarise, mlevels = get("mode", ".GlobalEnv")(levels))
cat mlevels
1 1 6
2 2 5
3 3 9