r - 使用 R 根据重复记录对数据进行分组
问题描述
我有一个包含重复记录/常见记录的数据集。它看起来像这样:
| Vendor | Buyer | Amount |
|--------|:-----:|-------:|
| A | P | 100 |
| B | P | 150 |
| C | Q | 300 |
| A | P | 290 |
我需要将类似的记录组合在一起,但我不想总结我的数量。我想单独表示金额值。输出应该是这样的:
| Vendor | Buyer | Amount |
|--------|:-----:|-------:|
| A | P | 100 |
| A | P | 290 |
| | | |
| B | P | 150 |
| | | |
| C | Q | 300 |
我曾想过使用 split(),但由于我的原始数据有太多记录,因此 split 函数会创建太多列表,并且从它们创建新数据集变得很乏味。如何使用任何其他方法实现上述输出?
编辑:让我们假设我们有一个名为 date 的附加列,数据集现在看起来像这样:
| Vendor | Buyer | Amount | Date |
|--------|:-----:|-------:|-----------|
| A | P | 100 | 3/6/2019 |
| B | P | 150 | 7/6/2018 |
| C | Q | 300 | 4/21/2018 |
| A | P | 290 | 6/5/2018 |
曾经,每个买家和供应商都被分组在一起,我需要为每个买家和供应商按升序排列日期,使其看起来像下面这样:
| Vendor | Buyer | Amount | Date |
|--------|:-----:|-------:|-----------|
| A | P | 290 | 6/5/2018 |
| A | P | 100 | 3/6/2019 |
| | | | |
| B | P | 150 | 7/6/2018 |
| | | | |
| C | Q | 300 | 4/21/2018 |
然后删除单个事务以获得仅包含的最终表
| Vendor | Buyer | Amount | Date |
|--------|:-----:|-------:|----------|
| A | P | 290 | 6/5/2018 |
| A | P | 100 | 3/6/2019 |
解决方案
在下文中,我们对数据框进行排序并添加一个组列,以便对各个组进行后续处理。例如,要在不创建大量拆分的情况下处理组DF
:
for(g in unique(DFout$group)) {
DFsub <- subset(DFout, group == g)
... process DFsub ...
}
1) Base R对数据进行排序,然后使用cumsum
非重复元素分配组列。
library(data.table)
o <- with(DF, order(Vendor, Buyer))
DFo <- DF[o, ]
DFout <- transform(DFo, group = cumsum(!duplicated(data.frame(Vendor, Buyer))))
DFout
给予:
Vendor Buyer Amount group
1 A P 100 1
4 A P 290 1
2 B P 150 2
3 C Q 300 3
我不确定这是否是一个好主意,但如果你真的想在每个组之后添加一行 NA:
ix <- unname(unlist(tapply(DFout$group, DFout$group, function(x) c(x, NA))))
ix[!is.na(ix)] <- seq_len(nrow(DFout))
DFout[ix, ]
2)data.table 转换为data.table,设置key(对其进行排序)并用于rleid
分配组号。
library(data.table)
DT <- data.table(DF)
setkey(DT, Vendor, Buyer)
DT[, group := rleid(Vendor, Buyer)]
3) sqldf另一种方法是使用SQL。这需要github 上的 RSQLite开发版本。这里dense_rank
的行为与上面类似rleid
。
library(sqldf)
sqldf("select *, dense_rank() over (order by Vendor, Buyer) as [group]
from DF
order by Vendor, Buyer")
给予:
Vendor Buyer Amount group
1 A P 100 1
2 A P 290 1
3 B P 150 2
4 C Q 300 3
笔记
DF <- structure(list(Vendor = structure(c(1L, 2L, 3L, 1L), .Label = c("A",
"B", "C"), class = "factor"), Buyer = structure(c(1L, 1L, 2L,
1L), .Label = c("P", "Q"), class = "factor"), Amount = c(100L,
150L, 300L, 290L)), class = "data.frame", row.names = c(NA, -4L
))
推荐阅读
- npm - Gatsby 网站已构建,但打开 localhost 时出现“UnhandledPromiseRejectionWarning:TypeError:无法读取 parseError 处未定义的属性“split””
- python - 具有自定义功能的数据排序
- javascript - 是否可以使用 jest 将测试导入另一个文件?
- reactjs - 在生产环境中为 React/Express 应用代理 api 请求
- python - Python:使 Rich 不设置字符串样式
- r - R中“字典”数据帧的多种模式和替换,也许是gsub?
- kotlin - 我们如何在 ktor 中模拟 CoroutineDatabase?
- python - 如何传递此错误“ValueError:在 Python 中解包的值太多(预期为 2)?”
- hadoop - Hadoop start-dfs.sh 无法启动节点
- php - 如何调用 .bat 文件而不是将整个路径写入 .exe?