根据计数创建摘要数据框

时间:2016-09-28 04:46:45

标签: r

我正在尝试使用数据框来创建摘要计数的第二个数据框。我的原始数据具有以下结构:

mydata <- read.table(header=TRUE, text="
item    type    store1  store2  store3  store4  store5
chair   timber  0   1   4   0   6
chair   metal   0   1   4   1   9
chair   upholstered 3   0   0   1   1
table   indoor  1   8   0   1   0
table   outdoor 1   12  2   1   0
bed single  0   0   2   1   0
bed double  0   1   1   1   0
bed queen   1   0   0   1   3
bed king    5   0   1   3   0")

我希望我的摘要数据框能够计算每个商店中存在的每种类型的家具,并总结每个商店的库存(只是在场/不在场,而不是项目数)。它应该是这样的:

summary <- read.table(header=TRUE, text="
store   chair_types table_types bed_types   total_types
store1  1   2   2   5
store2  2   2   1   5
store3  2   1   3   6
store4  2   2   4   8
store5  3   0   1   4")

这在excel中很容易,但我试图咬紧牙关并学会正确地做到这一点。如果这是重复的道歉,但我找不到类似的例子。提前谢谢。

2 个答案:

答案 0 :(得分:3)

我们可以使用dplyr/tidyr执行此操作。按照&#39;项目&#39;进行分组后,循环显示&#39;商店&#39;列(summarise_each),获取每个&#39;存储&#39;中的非零元素的数量。列(sum(.!=0),转换为&#39; long&#39;格式(gather),paste子格式&#39; _types&#39;到&#39;项目&#39;,spread&#39; long&#39;格式化为&#39; wide&#39;并创建一个&#39; total&#39;使用rowSums

的列
library(dplyr)
library(tidyr)
mydata %>% 
     group_by(item) %>%
     summarise_each(funs(sum(.!=0)), store1:store5) %>% 
     gather(store, val, store1:store5) %>% 
     mutate(item = paste0(item, "_types")) %>%
     spread(item, val) %>%
     mutate(total = rowSums(.[-1]))
#   store bed_types chair_types table_types total
#   <chr>     <int>       <int>       <int> <dbl>
#1 store1         2           1           2     5
#2 store2         1           2           2     5
#3 store3         3           2           1     6
#4 store4         4           2           2     8
#5 store5         1           3           0     4

这也可以通过首先转换为&#39; long&#39;格式,按&#39; item&#39;,&#39; store&#39;分组,获取非零元素的数量(summarise),按&#39; store&#39;分组,创建&#39; Total&#39;列添加了&#39; val&#39;然后spread

mydata %>% 
     gather(store, val, store1:store5) %>%
     group_by(item, store) %>% 
     summarise(val = sum(val!=0)) %>% 
     group_by(store) %>% 
     mutate(Total = sum(val)) %>% 
     spread(item, val)

我们也可以使用base Rrowsum

轻松完成addmargins
addmargins(t(rowsum(+(mydata[-(1:2)]!=0), mydata[,1])), 2)
#       bed chair table Sum
#store1   2     1     2   5
#store2   1     2     2   5
#store3   3     2     1   6
#store4   4     2     2   8
#store5   1     3     0   4

答案 1 :(得分:3)

您想要的核心可以使用基础R aggregate包中的R函数stats来完成

> aggregated <- aggregate(mydata[grep("store",names(mydata))], 
                          by = mydata["item"], 
                          FUN = function(x) sum(x != 0))
> aggregated
   item store1 store2 store3 store4 store5
1   bed      2      1      3      4      1
2 chair      1      2      2      2      3
3 table      2      2      1      2      0

第一个参数mydata[grep("store",names(mydata))]正在从数据框中选择“存储”。第二个参数by = mydata["item"]表示您希望使用“item”来标识数据框中的组。最后,FUN = function(x) sum(x != 0)表示您要计算每个商店列的每个商品的非零元素数。

这可能就足够了,但是如果你想重新格式化它,你可以做的更像:

> summary <- as.data.frame(t(aggregated[-1]))
> names(summary) <- aggregated[[1]]
> summary[["total"]] <- rowSums(summary)
> summary
       bed chair table total
store1   2     1     2     5
store2   1     2     2     5
store3   3     2     1     6
store4   4     2     2     8
store5   1     3     0     4