plyr :: mutate和dplyr :: mutate之间的区别

时间:2015-03-02 14:44:04

标签: r plyr dplyr

  

dplyr::mutate()的工作方式与plyr::mutate()相同,与base::transform()类似。 mutate()transform()之间的主要区别在于mutate允许您引用刚刚创建的列。 - dplyr简介

mutatedplyr中的plyr功能存在一些差异。主要区别当然是plyr::mutate可以应用于list,而dplyr::mutate更快。

此外,在引用刚刚创建的列时,plyr无法再次重新分配它们,但dplyr会这样做。

# creating a temporary variable and removing it later
plyr::mutate(data.frame(a = 2), tmp = a, c = a*tmp, tmp = NULL) 
## a tmp c
## 1 2   2 4
dplyr::mutate(data.frame(a = 2), tmp = a, c = a*tmp, tmp = NULL)
## a c
## 1 2 4

# creating a temporery variable and changing it later
plyr::mutate(data.frame(a = 2), b = a, c = a*b, b = 1)
## a b c
## 1 2 2 4
dplyr::mutate(data.frame(a = 2), b = a, c = a*b, b = 1)
## a b c
## 1 2 1 4

现在我正在为dplyr个对象寻找mutate list函数的功能。所以我正在寻找一个改变list的函数,并且可以重新分配刚创建的变量。

plyr::mutate(list(a = 2), b = a, c = a*b, b = 1)
## $a
## [1] 2
## 
## $b
## [1] 2
## 
## $c
## [1] 4
dplyr::mutate(list(a = 2), b = a, c = a*b, b = 1)
## Error in UseMethod("mutate_") : 
##   no applicable method for 'mutate_' applied to an object of class "list"
desired_mutate(list(a = 2), b = a, c = a*b, b = 1)
## $a
## [1] 2
## 
## $b
## [1] 1
## 
## $c
## [1] 4

我意识到在这个简单的例子中,我可以使用

plyr::mutate(list(a = 2), c = {b = a; a*b})

但在我的实际使用案例中,我将随机数分配给临时变量,并希望之后将其删除。如下所示:

desired_mutate(list(a = c(1, 2, 5, 2)), 
                    tmp = runif(length(a)), 
                    b = tmp * a, 
                    c = tmp + a,
                    tmp = NULL)

1 个答案:

答案 0 :(得分:1)

更正了for函数中的原始mutate循环(使用cols位置而不是名称):

desired_mutate <- function (.data, ...) 
{
  stopifnot(is.data.frame(.data) || is.list(.data) || is.environment(.data))
  cols <- as.list(substitute(list(...))[-1])
  cols <- cols[names(cols) != ""]
  col_names <- names(cols)
  for (i in seq_along(col_names) ) {
    if(!is.null(cols[[i]])) {
      .data[[col_names[i]]] <- eval(cols[[i]], .data, parent.frame()) 
    } else {
      .data[[col_names[i]]] <- NULL
    }
  }
  .data
}

测试:

> str( desired_mutate(list(a = c(1, 2, 5, 2)), 
+                tmp = runif(length(a)), 
+                b = tmp * a, 
+                c = tmp + a,
+                tmp = NULL) )
List of 3
 $ a: num [1:4] 1 2 5 2
 $ b: num [1:4] 0.351 1.399 3.096 1.4
 $ c: num [1:4] 1.35 2.7 5.62 2.7