如何使用dplyr基于行数据生成新列?

时间:2015-05-20 06:05:35

标签: r dplyr

我想在数据框中添加一个基于行方式计算的新列。假设我有一个这样的数据框:

x <-as.data.frame(matrix(1:10, 5, 2))

  V1 V2
1  1  6
2  2  7
3  3  8
4  4  9
5  5 10

如果我想做一些rowwise操作来生成一个新列,我可以使用rowwise()和do()来完成它。例如:

y <- rowwise(x) %>% do (foo = .$V1 * .$V2)

我甚至可以将其附加到现有数据框中:

y <- rowwise(x) %>% bind_cols(do (., foo = .$V1 * .$V2))

这一切都有效,但结果并不是我想要的。 y $ foo中的值是列表,而不是数字。

  V1 V2 foo
1  1  6   6
2  2  7  14
3  3  8  24
4  4  9  36
5  5 10  50

看起来正确,但它不是。

class(y$foo)
[1] "list"

所以,有两个问题:

  1. 有没有办法让结果数字而不是列表?
  2. 我有更好的方法来接近这个吗?
  3. 更新
    这更接近我想要做的事情。鉴于此功能:

    pts <- 11:20
    z <- function(x1, x2) {
      min(x1*x2*pts)
    }
    

    这并不能产生我的期望:

    y <- x %>% mutate(foo = z(V1, V2))
      V1 V2 foo
    1  1  6  66
    2  2  7  66
    3  3  8  66
    4  4  9  66
    5  5 10  66
    

    虽然这样做:

    y <-rowwise(x) %>% bind_cols( do (., data.frame(foo = z(.$V1, .$V2))))
      V1 V2 foo
    1  1  6  66
    2  2  7 154
    3  3  8 264
    4  4  9 396
    5  5 10 550
    

    为什么呢?还有更好的方法吗?

3 个答案:

答案 0 :(得分:6)

我通常不相信像R这样的矢量化语言中的行式操作。在你的情况下,你可以通过简单的矩阵乘法来解决问题。

您可以按如下方式定义public func addSubscriber(subscriber: JABPanelChangeSubscriber) { if !contains(subscribers, { $0 === subscriber } ) { subscribers.append(subscriber) } }

z

比简单的z <- function(x1, x2) { do.call(pmin, as.data.frame(tcrossprod(x1 * x2, pts))) }

mutate

您还可以使用x %>% mutate(foo = z(V1, V2)) # V1 V2 foo # 1 1 6 66 # 2 2 7 154 # 3 3 8 264 # 4 4 9 396 # 5 5 10 550 函数(完全矢量化)

来提高性能
matrixStats::rowMins

答案 1 :(得分:4)

您应该在data.frame声明中返回do

y <- rowwise(x) %>% bind_cols(do(., data.frame(foo = .$V1 * .$V2)))
y
##   V1 V2 foo
## 1  1  6   6
## 2  2  7  14
## 3  3  8  24
## 4  4  9  36
## 5  5 10  50
y$foo
## [1]  6 14 24 36 50

在您更新的问题中,您错过了rowwise语句链中的mutate,但链中的rowwise带有do语句。只需添加rowwise即可获得相同的结果。

x %>% rowwise %>% mutate(foo = z(V1, V2))
## Source: local data frame [5 x 3]
## Groups: <by row>
## 
##   V1 V2 foo
## 1  1  6  66
## 2  2  7 154
## 3  3  8 264
## 4  4  9 396
## 5  5 10 550

答案 2 :(得分:1)

x <-as.data.frame(matrix(1:10, 5, 2))

foo <- apply(x , 1 , function(x){
  prod(x)
})

#[1]  6 14 24 36 50

class(foo)

#[1] "numeric"

df_final <- cbind(x , foo)