使用 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( 基本 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,设置键(对其进行排序(并使用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
))

相关内容

  • 没有找到相关文章

最新更新