无论列

时间:2017-10-25 15:37:06

标签: r dataframe

我想将数据框聚合两列,以便它们的变体只存在一次。值列应由max()sum()

等聚合函数聚合

数据:

itemID1  |itemID2  |value
---------|---------|-------
B0001    |B0001    |1
B0002    |B0001    |1
B0001    |B0002    |2
B0002    |B0002    |0

结果可能是:

itemID1   |itemID2   |value
----------|----------|---------
B0001     |B0001     |1
B0001     |B0002     |3          #itemIDs could also be ordered in the other way
B0002     |B0002     |0

到目前为止,我已在SQL中实现它以通过库sqldf使用它,但是sqldf不支持WITH子句。

是否有可能直接在R?

中聚合这样的数据帧

4 个答案:

答案 0 :(得分:8)

base R中,但它会复制数据,因为我处理的是一份副本,保持原文不变。

dat2 <- dat
dat2[1:2] <- apply(dat2[1:2], 1, sort)
aggregate(value ~ itemID1 + itemID2, dat2, sum)
#  itemID1 itemID2 value
#1   B0001   B0001     1
#2   B0001   B0002     3
#3   B0002   B0002     0

现在你可以rm(dat2)来整理。

数据。

dat <-
structure(list(itemID1 = structure(c(1L, 2L, 1L, 2L), .Label = c("B0001", 
"B0002"), class = "factor"), itemID2 = structure(c(1L, 1L, 2L, 
2L), .Label = c("B0001", "B0002"), class = "factor"), value = c(1L, 
1L, 2L, 0L)), .Names = c("itemID1", "itemID2", "value"), class = "data.frame", row.names = c(NA, 
-4L))

答案 1 :(得分:4)

dplyrpmin / pmax

library(dplyr)
df1 %>%
  mutate(ItemID1_ = pmin(itemID1  ,itemID2),
         ItemID2_ = pmax(itemID1  ,itemID2)) %>%
  group_by(ItemID1_,ItemID2_) %>%
  summarize_at("value",sum) %>%
  ungroup

# # A tibble: 3 x 3
#   ItemID1_ ItemID2_ value
#      <chr>    <chr> <int>
# 1    B0001    B0001     1
# 2    B0001    B0002     3
# 3    B0002    B0002     0

关注@ A5C1D2H2I1M1N2O1R2T1的评论后,您可以跳过mutate部分并使用相同的输出:

df1 %>%
  group_by(itemID1_ = pmin(itemID1, itemID2),
           itemID2_ = pmax(itemID1, itemID2)) %>%
  summarise_at("value", sum) %>%
  ungroup

答案 2 :(得分:4)

如果你想坚持sqldf

,这是另一种解决方案
library(sqldf)

sqldf("select itemID1, itemID2, sum(value) as value 
          from (select case when itemID1 <= itemID2 then itemID1 else itemID2 end as itemID1,
                       case when itemID1 > itemID2 then itemID1 else itemID2 end as itemID2,
                       value
                from df)
      group by itemID1, itemID2")

<强>结果:

  itemID1 itemID2 value
1   B0001   B0001     1
2   B0001   B0002     3
3   B0002   B0002     0

数据:

df = structure(list(itemID1 = structure(c(1L, 2L, 1L, 2L), .Label = c("B0001", 
"B0002"), class = "factor"), itemID2 = structure(c(1L, 1L, 2L, 
2L), .Label = c("B0001", "B0002"), class = "factor"), value = c(1L, 
1L, 2L, 0L)), .Names = c("itemID1", "itemID2", "value"), class = "data.frame", row.names = c(NA, 
-4L))

答案 3 :(得分:3)

为了完整起见,这里还有一个data.table解决方案:

library(data.table)
setDT(DT)[, .(value = sum(value)), 
   by = .(itemID1 = pmin(itemID1, itemID2), itemID2 = pmax(itemID1, itemID2))]
   itemID1 itemID2 value
1:   B0001   B0001     1
2:   B0001   B0002     3
3:   B0002   B0002     0

数据

DT <- fread("itemID1  |itemID2  |value
B0001    |B0001    |1
B0002    |B0001    |1
B0001    |B0002    |2
B0002    |B0002    |0", sep = "|")