R:使用自定义函数分组

时间:2015-02-19 21:03:18

标签: r data.table

我已成功使用以下模式聚合数据:

newdf <- setDT(df)[, list(X=sum(x),Y=max(y)), by=Z]

然而,当我尝试做更复杂的事情的那一刻,虽然代码运行,它不再由Z聚合:它似乎创建一个与原始df具有相同观察数量的数据帧,所以我知道没有分组是实际上正在发生。

我想要应用的自定义函数是找到当前值列表的n分位数,然后用它做一些其他的东西。我在另一个SO答案中看到了使用sdcols并尝试了类似的东西:

customfunc <- function(dt){
q = unname(quantile(dt$column,0.25))
n = nrow(dt[dt$column <= q])
return(n/dt$someOtherColumn)
}
#fails to group anything!!! also rather slow...
newdf <- setDT(df)[, customfunc(.SD), by=Z, .SDcols=c(column, someOtherColumn)]

有人可以帮我弄清楚我尝试使用分组和自定义功能的方式有什么问题吗?非常感谢你。

要求的文字示例:

> df <- data.frame(Z=c("abc","abc","def","abc"), column=c(1,2,3,4), someOtherColumn=c(5,6,7,8))
> df
    Z column someOtherColumn
1 abc      1               5
2 abc      2               6
3 def      3               7
4 abc      4               8
> newdf <- setDT(df)[, customfunc(.SD), by=Z, .SDcols=c("column", "someOtherColumn")]
> newdf
     Z        V1
1: abc 0.2000000
2: abc 0.1666667
3: abc 0.1250000
4: def 0.1428571
> 

如您所见,DF未分组。应该只有两行,一行用于“abc”,另一行用于“def”,因为我试图按Z分组。

1 个答案:

答案 0 :(得分:4)

在eddi的上述指导下,基本问题是认为您的自定义函数是在循环内调用的,并且dt$column&#39;将神秘地给你当前行的当前值#39;相反,它为您提供整个列(向量)。该函数传递整个数据表,而不是行数据位。

因此,将return语句中的值替换为表示单个值的值。例如:

customfunc <- function(dt){
  q = unname(quantile(dt$column,0.25))
  n = nrow(dt[dt$column <= q])
  return(n/length(dt$someOtherColumn))
}

> df <- data.frame(Z=c("abc","abc","def","abc"), column=c(1,2,3,4), someOtherColumn=c(5,6,7,8))
> df
    Z column someOtherColumn
1 abc      1               5
2 abc      2               6
3 def      3               7
4 abc      4               8
> newdf <- setDT(df)[, customfunc(.SD), by=Z, .SDcols=c("column", "someOtherColumn")]
> newdf
     Z        V1
1: abc 0.3333333
2: def 1.0000000

现在数据已正确汇总。