首页 > 解决方案 > 获取一对行的总和

问题描述

我在 R 中导入了以下数据框:

product per1  per2  per3
A       10    20    30
B       23    14    21
C       26    95    81

将 A:C 视为逐行列出的产品,以及它们在 per_1:per_3 中的相应销售值,这些值在列中给出。

产品数量很多,所以无法列出所有产品我这里的要求是添加产品组合的销售额。

例如

A      10    20   30
B      23    14   21

总和应该是

myresult<- A+B
myresult
33 34 51

总和应该是 30 34 80,并且应该复制到另一个向量。

产品的数量如此之多,以至于我无法将它们转置并用于计算。假设要添加的产品组合也很高且随机。

这是我的数据:

structure(list(product = structure(1:3, .Label = c("A", "B", "C"), class = "factor"), 
               per1 = c(10, 20, 30), 
               per2 = c(23, 14, 21), 
               per3 = c(26, 95, 81)), 
          .Names = c("product", "per1", "per2", "per3"), 
          row.names = c(NA, -3L), class = "data.frame")

标签: rdataframerowsummarizedata-wrangling

解决方案


我们可以按每对行制作数据框,然后通过对每列求和并将产品名称放入列表来汇总这些对。在这里,我使用dplyrpurrr包,但它可以base类似地完成。

library(dplyr)
library(purrr)
id.row <- combn(nrow(df1),2) ## to get a matrix with ids of each pair of rows

## first I create a list of dataframes with pair of rows
map(1:ncol(id.row), function(i) 
                          rbind(df1[id.row[1,i], ], df1[id.row[2,i], ])) %>% 
## then I summarize them based on column class (converting factors to character first)
  map(. %>% 
        mutate_if(is.factor, as.character) %>% 
        summarise_each(funs(if(is.numeric(.)) sum(., na.rm = TRUE) else list(.))))
#> [[1]]
#>   product per1 per2 per3
#> 1    A, B   33   34   51
#> 
#> [[2]]
#>   product per1 per2 per3
#> 1    A, C   36  115  111
#> 
#> [[3]]
#>   product per1 per2 per3
#> 1    B, C   49  109  102

如果您有要成对求和的一组特定行列表,则可以执行以下操作:

## specific pair of rows as you need
id.row <- cbind(c("A", "B"), c("B", "C"))

## first I create a list of dataframes with pair of rows
map(1:ncol(id.row), function(i) 
  rbind(df1[df1$product==id.row[1,i],], df1[df1$product==id.row[2,i],])) %>% 
  ## then I summarize them based on column class (converting factors to character first)
  map(. %>% 
        mutate_if(is.factor, as.character) %>% 
        summarise_each(funs(if(is.numeric(.)) sum(., na.rm = TRUE) else list(.))))
#> [[1]]
#>   product per1 per2 per3
#> 1    A, B   33   34   51
#> 
#> [[2]]
#>   product per1 per2 per3
#> 1    B, C   49  109  102

数据

df1 <- read.table(text="product per1  per2  per3
                          A       10    20    30
                          B       23    14    21
                          C       26    95    81", header=T)

推荐阅读