【问题标题】:creating a function and subset of data frame is not working in aggregate function创建函数和数据框的子集在聚合函数中不起作用
【发布时间】:2017-05-14 21:28:53
【问题描述】:

我遇到了一个奇怪的问题,如果我在自定义函数中调用聚合函数,它的行为就会很奇怪。它似乎完全超过了子集函数:

为了让您了解问题所在,我将其分为两部分。 1.没有自定义功能

    c<- data.frame(A = c("carr","bike","truck","carr","truck","bike","bike","carr","truck","carr","truck","truck","carr","truck","truck"),
                B = c(10,20,30,23,45,56,78,44,10,20,30,10,20,30,67),
                D = c(1,2,3,1,2,3,2,3,2,3,2,2,3,2,1))

c_subset<- subset(c,(A=="carr")|(A=="bike"))

dg<- aggregate(B ~ D + A  ,c_subset,max)

dg 的值为:

D   A   B           
2   bike    78
3   bike    56
1   carr    23
3   carr    44

这正是它应该的样子。

但是 2.带自定义功能:

 rtk <- function(datam,inc_coll,inc_vall,lb,ld){
  datam_subset <- subset(c,inc_coll %in% inc_vall)
  dg1<- aggregate(lb ~ ld + inc_coll,datam_subset,max)

  return(dg1)
}

c_ans <- rtk(c,c$A,c("carr","bike"),c$B,c$D)

答案是:

ld  inc_coll    lb

2   bike    78
3   bike    56
1   carr    23
3   carr    44
1   truck   67
2   truck   45
3   truck   30

现在我想知道为什么它在聚合函数中得到“卡车”? 虽然在聚合函数中我使用了数据 datam_subset,它是一个子集,只包含“carr”和“bike”的数据。

可能是我遗漏了一些非常基本的东西。应感谢您的帮助。谢谢

【问题讨论】:

  • 您为函数rtk 提供原始数据框的实际列,而不仅仅是列名。所以subset 有效,但随后aggregatec 的列上完成。
  • 因为没有人真正提到它。 stackoverflow.com/questions/9860090/why-is-better-than-subset 给出了在函数中使用子集的一些想法。聚合还有一个子集参数,这可能会使事情变得更容易
  • datam 参数永远不会在函数内部使用,尽管您将 c 传递给它

标签: r aggregate subset custom-function


【解决方案1】:

将列名传递给函数是一个经常被问到的问题,因为它可能违反直觉。检查这个问题:Pass a data.frame column name to a function 编写函数的更好方法是将列名而不是列本身传递给 rtk,然后将它们用于您想做的事情:

rtk <- function(datam,inc_coll,inc_vall,lb,ld){
## Access the column using df[[colname]] to do the subset
  datam_subset <- subset(c,c[[inc_coll]] %in% inc_vall);
## Define the formula you will use in the aggregate function
f=as.formula(paste0(lb,"~",ld,"+", inc_coll))
## Perform the aggregation
  dg1<- aggregate(f,datam_subset,max);
  return(dg1)
}

然后使用列名适当地调用它:

c_ans <- rtk(c,"A",c("carr","bike"),"B","D")

这给了你:

D    A  B
1 2 bike 78
2 3 bike 56
3 1 carr 23
4 3 carr 44

【讨论】:

  • 感谢 Lamia 的详细解释。 @Yannis 解决方案也有效,但您的解决方案更具可配置性。
【解决方案2】:

这是因为你的聚合函数是从两个 data.frames 调用的

这个:

dg1<- aggregate(lb ~ ld + inc_coll, datam_subset, max)

实际上是这样的:

dg1<- aggregate(c$B ~ c$D + c$A, datam_subset, max)

所以您将覆盖 datam_subset 调用并简单地调用 c

【讨论】:

    【解决方案3】:

    实际上有两个问题。首先,正如其他人所指出的那样,您将 c 子集而不是 datam 子集,但这同样不能解决问题。 datam_subset 没有名为 lb, ld, inc_call 的列。所以你的函数应该是这样的:

    rtk <- function(datam, inc_coll, inc_vall, lb, ld){
      datam_subset <- subset(datam, inc_coll %in% inc_vall)
      names(datam_subset)<- c("inc_coll", "lb", "ld")
      dg1<- aggregate(lb ~ ld + inc_coll,datam_subset,max)
      return(dg1)
    }
    
    > c_ans <- rtk(c,c$A,c("carr","bike"),c$B, c$D)
    > c_ans
      ld inc_coll lb
    1  2     bike 78
    2  3     bike 56
    3  1     carr 23
    4  3     carr 44
    

    您可以将名称更改为c_ans,只需colnames(c_ans)&lt;- c("D", "A", "B")

    【讨论】:

      猜你喜欢
      • 2013-06-06
      • 1970-01-01
      • 2013-10-05
      • 2020-08-02
      • 2018-11-21
      • 2018-04-12
      • 2014-07-02
      • 1970-01-01
      • 2017-09-27
      相关资源
      最近更新 更多