R根据辅助字段条件在数据帧上获取唯一记录
更新和简化 我有一个非常大的表(约700万条记录),其结构如下R根据辅助字段条件在数据帧上获取唯一记录,r,R,更新和简化 我有一个非常大的表(约700万条记录),其结构如下 temp <- read.table(header = TRUE, stringsAsFactors=FALSE, text = "Website Datetime Rating A 2007-12-06T14:53:07Z 1 A 2006-07-28T03:52:26Z 4 B 2006-11-02T11:06:25Z 2 C 2007-
temp <- read.table(header = TRUE, stringsAsFactors=FALSE,
text = "Website Datetime Rating
A 2007-12-06T14:53:07Z 1
A 2006-07-28T03:52:26Z 4
B 2006-11-02T11:06:25Z 2
C 2007-06-19T06:56:08Z 5
C 2009-11-28T22:27:58Z 2
C 2009-11-28T22:28:13Z 2")
我试着使用for循环,但太慢了。是否有其他方法可以实现这一点。我可能会探索
数据表
包,但如果没有更多详细信息,下面的示例解决方案很可能不是您所需要的。我提到这一点是因为,特别是,每个组可能有多个与max
匹配的“评级”记录;你想如何处理这些案件
library(data.table)
temp <- read.table(header = TRUE, stringsAsFactors=FALSE,
text = "Website Datetime Rating
A 2012-10-9 10
A 2012-11-10 12
B 2011-10-9 5")
DT <- data.table(temp, key="Website")
DT
# Website Datetime Rating
# 1: A 2012-10-9 10
# 2: A 2012-11-10 12
# 3: B 2011-10-9 5
DT[, list(Datetime = Datetime[which.max(Rating)],
Rating = max(Rating)), by = key(DT)]
# Website Datetime Rating
# 1: A 2012-11-10 12
# 2: B 2011-10-9 5
如果您只想查看
评级
列,有很多方法可以做到这一点。按照与上述相同的步骤转换为数据表
,请尝试:
DT[, list(Datetime = max(Rating)), by = key(DT)]
Website Datetime
# 1: A 4
# 2: B 2
# 3: C 5
或者,保留原始的“temp”data.frame
,尝试aggregate()
:
另一种方法是使用
ave
:
temp[with(temp, Rating == ave(Rating, Website, FUN=max)), ]
由于“Datetime”变量看起来还不是日期或日期时间对象,因此您可能应该首先转换为日期对象
which.max
将选择最大值的第一项
> which.max(c(1,1,2,2))
[1] 3
所以阿南达在这方面的警告可能是不正确的。如果机器内存有限,Datatable方法肯定会更快,也可能成功。上述方法可能会同时复制多个数据。表函数不需要复制太多数据。我会
拆分数据,并使用lappy
浏览每个网站,应用您的标准。帮助我们,节能人士,提供一个可复制的例子和预期的结果。谢谢罗曼!我更新了我的问题,使之更加具体。你能给我举一个例子,说明如何将split与lapply结合起来以获得期望的结果吗?我认为@RomanLuštrik提到的split
和lapply
的想法与DWin在回答中的想法是一致的。另外,请参阅我的答案的更新,以匹配符合您条件的所有行。非常感谢您的帮助。每个类别可以有多个最大值。例如,在一个网站的例子中,评分可能都是10。@MichaelTsikerdekis,好的,那又怎样?正如我提到的,请用更现实的数据样本更新您的问题,同时提及您预期会遇到的瓶颈类型以及您希望如何处理它们。例如,如果有多个max值,您希望所有行都匹配该条件,还是第一行匹配该条件就足够了(正如which.max
所示)。我刚刚更新了帖子并简化了问题。这可能会让问题变得更清楚,更容易解决。“我试着自己去做,但到目前为止失败得很惨。”据我所知,我最初的答案仍然适用。你试过了吗?阿南达真的很管用!非常感谢,也感谢data.table的想法。我以前从未使用过它,而且它似乎比data.frame.DWin快得多。我的名字从来都不对(…虽然我知道他也有一个很难取对的名字:)
aggregate(Rating ~ Website, temp, max)
Website Rating
# 1 A 4
# 2 B 2
# 3 C 5
temp[with(temp, Rating == ave(Rating, Website, FUN=max)), ]
do.call( rbind, lapply( split(temp, temp$Website) ,
function(d) d[ which.max(d$Rating), ] ) )
Website Datetime Rating
A A 2006-07-28T03:52:26Z 4
B B 2006-11-02T11:06:25Z 2
C C 2007-06-19T06:56:08Z 5
> which.max(c(1,1,2,2))
[1] 3