我正在尝试使用数据框来创建摘要计数的第二个数据框。我的原始数据具有以下结构:
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中很容易,但我试图咬紧牙关并学会正确地做到这一点。如果这是重复的道歉,但我找不到类似的例子。提前谢谢。
答案 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 R
和rowsum
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