df library(sqldf) > sqldf("Se-6ren">
gpt4 book ai didi

sql - SQL "SELECT * FROM table GROUP BY c1, c2"的 R 等价物是什么?

转载 作者:行者123 更新时间:2023-12-04 23:20:55 25 4
gpt4 key购买 nike

我想将我的数据框( 编辑: 以 CPU 高效的方式)减少到具有 c3、c4 对唯一值的行,同时保留所有列。换句话说,我想转换我的数据框

> df <- data.frame(c1=seq(7), c2=seq(4, 10), c3=c("A", "B", "B", "C", "B", "A", "A"), c4=c(1, 2, 3, 3, 2, 2, 1))
c1 c2 c3 c4
1 1 4 A 1
2 2 5 B 2
3 3 6 B 3
4 4 7 C 3
5 5 8 B 2
6 6 9 A 2
7 7 10 A 1
到数据框
  c1 c2 c3 c4
1 1 4 A 1
2 2 5 B 2
3 3 6 B 3
4 4 7 C 3
6 6 9 A 2
其中 c1 和 c2 的值可以是出现在唯一对 c3、c4 中的任何值。同样,结果数据帧的顺序也不重要。
编辑:我的数据框大约有 250 000 行和 12 列,应该按 2 列分组——因此 我需要一个 CPU 高效的解决方案 .
工作但不令人满意的替代方案
我解决了这个问题
> library(sqldf)
> sqldf("Select * from df Group By c3, c4")
但为了加速和并行化我的程序,我必须消除对 sqldf 的调用。
编辑:目前 sqldf 解决方案时钟为 3.5 秒。我认为这是一个体面的时间。问题是我无法并行启动各种查询,因此我正在寻找替代方法。
不工作的尝试
复制()
> df[duplicated(df, by=c("c3", "c4")),]
[1] c1 c2 c3 c4
<0 rows> (or 0-length row.names)
选择重复的行而不选择只有 c3 和 c4 列重复的行。
总计的()
> aggregate(df, by=list(df$c3, df$c4))
Error in match.fun(FUN) : argument "FUN" is missing, with no default
聚合需要一个函数应用于所有具有相同 c3 和 c4 值的行
数据表的由
> library(data.table)
> dt <- data.table(df)
> dt[,list(c1, c2) ,by=list(c3, c4)]
c3 c4 c1 c2
1: A 1 1 4
2: A 1 7 10
3: B 2 2 5
4: B 2 5 8
5: B 3 3 6
6: C 3 4 7
7: A 2 6 9
不会踢出具有非唯一值 c3 和 c4 的行,而
> dt[ ,length(c1), by=list(c3, c4)]
c3 c4 V1
1: A 1 2
2: B 2 2
3: B 3 1
4: C 3 1
5: A 2 1
确实会丢弃 c1 和 c2 的值,并将它们缩减为由传递的函数 length 指定的一维.

最佳答案

这是一个 data.table 解决方案。

library(data.table)
setkey(setDT(df),c3,c4) # convert df to a data.table and set the keys.
df[,.SD[1],by=list(c3,c4)]
# c3 c4 c1 c2
# 1: A 1 1 4
# 2: A 2 6 9
# 3: B 2 2 5
# 4: B 3 3 6
# 5: C 3 4 7

您提出的 SQL 似乎提取了具有 (c3,c4) 给定组合的第一行 - 我认为这就是您想要的。

编辑 : 对 OP 评论的回应。

你引用的结果似乎很奇怪。下面的基准测试在具有 12 列和 2.5e5 行的数据集上显示,data.table 解决方案运行时间约为 25 毫秒 无需设置键,设置键后约 7 毫秒。
set.seed(1)  # for reproducible example
df <- data.frame(c3=sample(LETTERS[1:10],2.5e5,replace=TRUE),
c4=sample(1:10,2.5e5,replace=TRUE),
matrix(sample(1:10,2.5e6,replace=TRUE),nc=10))
library(data.table)
DT.1 <- as.data.table(df)
DT.2 <- as.data.table(df)
setkey(DT.2,c3,c4)
f.nokeys <- function() DT.1[,.SD[1],by=list(c3,c4)]
f.keys <- function() DT.2[,.SD[1],by=list(c3,c4)]
library(microbenchmark)
microbenchmark(f.nokeys(),f.keys(),times=10)
# Unit: milliseconds
# expr min lq median uq max neval
# f.nokeys() 23.73651 24.193129 24.609179 25.747767 26.181288 10
# f.keys() 5.93546 6.207299 6.395041 6.733803 6.900224 10

你的数据集在哪些方面与这个不同?

关于sql - SQL "SELECT * FROM table GROUP BY c1, c2"的 R 等价物是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27193373/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com