用dplyr按行计算元素

时间:2018-02-13 15:17:20

标签: r dplyr tidyr summarize

我有一个数据集,其中数据的格式不是特别有用。这是一个较小的例子:

你有一副纸牌,发出十张牌,记录卡片,过程重复5次,并存储在5x10矩阵中。为简单起见,我们只会将卡片编号为1-13而不是Ace,1,2 ... King;每张卡四份,与他们的诉讼无关。

set.seed(7)
tmpdf=data.frame(matrix(0,nrow=5,ncol=10))

for(i in 1:nrow(tmpdf)) {
    tmpdf[i,]=sample(rep(c(1:13),each=4),size=10)
}
> tmpdf
  X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
1 13  6  2  1  3 10  4 11  2   5
2  3  3 10  2  6  1  7  1 11   4
3  9  4 13 12 12  1  8  6 11  13
4  9  4  3 13  5 10  6 13 10   5
5 11  5 10  6 11  4  1 10 10  13

每张卡片的栏目并不重要,但每张牌每张牌的份数是多少。我知道如何在循环中重新组织基础R,但不是整洁的方式。

newdf=data.frame(matrix(0,nrow=5,ncol=13))
names(newdf)=as.character(c(1:13))

for(i in 1:nrow(tmpdf)) {
    tmp=table(factor(as.numeric(tmpdf[i,])))
    newdf[i,names(tmp)]=tmp
}

> newdf
  1 2 3 4 5 6 7 8 9 10 11 12 13
1 1 2 1 1 1 1 0 0 0  1  1  0  1
2 2 1 2 1 0 1 1 0 0  1  1  0  0
3 1 0 0 1 0 1 0 1 1  0  1  2  2
4 0 0 1 1 2 1 0 0 1  2  0  0  2
5 1 0 0 1 1 1 0 0 0  3  2  0  1

我怀疑是计数和/或总结会有用,但到目前为止我还没有找到解决方案,也没有在这里找到问题/答案。

3 个答案:

答案 0 :(得分:1)

不是tidy方式,但无论如何都可能对您有用,因为它非常简短:

data.frame(sapply(1:13,function(x) {rowSums(tmpdf==x)}))

输出:

  X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13
1  1  2  1  1  1  1  0  0  0   1   1   0   1
2  2  1  2  1  0  1  1  0  0   1   1   0   0
3  1  0  0  1  0  1  0  1  1   0   1   2   2
4  0  0  1  1  2  1  0  0  1   2   0   0   2
5  1  0  0  1  1  1  0  0  0   3   2   0   1

希望这有帮助!

答案 1 :(得分:1)

一个简洁的方法是tidyr::gather所有值,dplyr::count,然后tidyr::spread他们

tmpdf %>%
  group_by(rn = row_number()) %>%
  gather(key, value, X1:X10) %>%
  ungroup() %>%
  count(rn, value) %>%
  group_by(rn) %>%
  spread(value, n, fill=0)

  # A tibble: 5 x 14
         # rn   `1`   `2`   `3`   `4`   `5`   `6`   `7`   `8`   `9`  `10`  `11`  `12`  `13`
    # * <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
    # 1     1  1.00  2.00  1.00  1.00  1.00  1.00  0     0     0     1.00  1.00  0     1.00
    # 2     2  2.00  1.00  2.00  1.00  0     1.00  1.00  0     0     1.00  1.00  0     0   
    # 3     3  1.00  0     0     1.00  0     1.00  0     1.00  1.00  0     1.00  2.00  2.00
    # 4     4  0     0     1.00  1.00  2.00  1.00  0     0     1.00  2.00  0     0     2.00
    # 5     5  1.00  0     0     1.00  1.00  1.00  0     0     0     3.00  2.00  0     1.00

答案 2 :(得分:0)

简洁的方法是

library(qdapTools)
mtabulate(as.data.frame(t(tmpdf)))
#   1 2 3 4 5 6 7 8 9 10 11 12 13
#V1 1 2 1 1 1 1 0 0 0  1  1  0  1
#V2 2 1 2 1 0 1 1 0 0  1  1  0  0
#V3 1 0 0 1 0 1 0 1 1  0  1  2  2
#V4 0 0 1 1 2 1 0 0 1  2  0  0  2
#V5 1 0 0 1 1 1 0 0 0  3  2  0  1

或在管道中使用mtabulate

tmpdf %>%
      t %>% 
      as_tibble %>%
      mtabulate

base R

table(stack(as.list(as.data.frame(t(tmpdf))))[2:1])