首页 文章

将名称分配给dplyr的列表输出执行操作

提问于
浏览
4

dplyr 中的 do 函数通常会生成列表 . 是否有办法根据 do 的输入为该列表指定名称?具体来说,我传递 group_by 结果,并希望列表的名称可以指示列表元素对应的组 .

这是我想要实现的目标的玩具示例:

> it = data.frame(ind=c("a","a","b","b","c"),var1=c(1,2,3,4,5), var1=c(2,3,4,2,2))
> group_by(it,ind)%.%summarise(min(var1))
Source: local data frame [3 x 2]

  ind min(var1)
1   c         5
2   b         3
3   a         1

现在用 do 做这个

> do(group_by(it,ind),function(x)min(x[,"var1"]))
[[1]]
[1] 5

[[2]]
[1] 3

[[3]]
[1] 1

理想情况下,名称应为 c("c","b","a") .

这可能吗?为什么 dplyr 会对群组进行排序?请注意,在我的情况下, do 操作的结果是 lm 对象 .

Edit: 评论要求提供真实的例子,这就是我的想法 . 我根据数据(虚拟代码)拟合模型:

res <- do(group_by(data,Index),lm,formula=y~x)

现在我想做各种各样的事情

sapply(res,coef)

所以我想将结果与原始数据集相关联,在这种情况下,系数对应于 Index .

Edit 2: 使用 dlply 函数可以实现所需的行为:

dlply(it,~ind,function(d)min(d[,"var1"]))

$a
[1] 1

$b
[1] 3

$c
[1] 5

attr(,"split_type")
[1] "data.frame"
attr(,"split_labels")
  ind
1   a
2   b
3   c

我正在研究是否可以使用dplyr复制此行为,最好是干预最少 .

2 回答

  • 1

    试试 do.grouped_df 的这个标记版本:

    do2 <- function (.data, .f, ...) {
        if (is.null(attr(.data, "indices"))) {
            .data <- dplyr:::grouped_df_impl(.data, attr(.data, "vars"), 
                attr(.data, "drop"))
        }
        index <- attr(.data, "indices")
        out <- vector("list", length(index))
        for (i in seq_along(index)) {
            subs <- .data[index[[i]] + 1L, , drop = FALSE]
            out[[i]] <- .f(subs, ...)
        }
        nms <- as.character(attr(.data, "labels")[[1]])
        setNames(out, nms)
    }
    
    library(gusbfn)
    
    it %.% group_by(ind) %.% do2(function(x) min(x$var1))
    

    这使:

    $a
    [1] 1
    
    $b
    [1] 3
    
    $c
    [1] 5
    

    它也可以与gsubfn包中的 fn$ 结合使用,以便稍微缩短它:

    library(dplyr)
    library(gsubfn)
    
    it %.% group_by(ind) %.% fn$do2(~ min(x$var1))
    

    给出相同的答案 .

  • 4

    您可以在函数中创建data.frame:

    mods <- do(group_by(it,ind),function(x)
            data.frame(it=unique(as.character(x$ind)),val=min(x$var1)))
    

    然后 :

    do.call(rbind,mods)
      it val
    1  a   1
    2  b   3
    3  c   5
    

    编辑

    mods <- do(group_by(it,ind),
          function(x) setNames(list(min(x$var1)),unique(as.character(x$ind))))
    
    unlist(mods,rec=FALSE)
    $a
    [1] 1
    
    $b
    [1] 3
    
    $c
    [1] 5
    

相关问题