我试图在R中做一些等同于SQL中“第一个值”窗口函数的东西,例如:
select *, first_value(value3) over (partition by value1, value2 order by value5 desc)
from df
有没有一种很好的方法在R中执行此操作而无需创建数据库来使用sqldf / RPostgreSQL之类的东西?
我在这里看到了其他一些例子:Cumulative sum by group in sqldf?
但是我在使用窗口中的顺序很重要的功能找出如何使用它时遇到了一些麻烦。另一件事是我正在使用~500K行,因此性能是一个问题。
编辑:这是一个例子:
item_id rental_date customer_id
I001 10/20/2012 1
I002 10/05/2012 4
I001 10/15/2012 3
I004 10/19/2012 1
I001 10/11/2012 6
I002 9/15/2012 5
I004 10/13/2012 10
I001 9/30/2012 4
我如何确定每个月租用特定物品的第一位顾客?
答案 0 :(得分:4)
如果不使用sqldf / PostgreSQL你的意思是使用sqldf但是使用SQLite而不是PostgreSQL然后尝试这个(它依赖于去年添加的SQLite的新功能,如果有最小值或最大值,那么其他列保证来自同一行):
Lines <- "item_id rental_date customer_id
I001 10/20/2012 1
I002 10/05/2012 4
I001 10/15/2012 3
I004 10/19/2012 1
I001 10/11/2012 6
I002 9/15/2012 5
I004 10/13/2012 10
I001 9/30/2012 4"
DF <- read.table(text = Lines, as.is = TRUE, header = TRUE)
DF$rental_date <- as.Date(DF$rental_date, "%m/%d/%Y")
DF$ym <- format(DF$rental_date, "%Y-%m")
sqldf("select item_id, ym, customer_id, min(rental_date) rental_date
from DF
group by item_id, ym")
这种情况的结果是:
item_id ym customer_id rental_date
1 I001 2012-09 4 2012-09-30
2 I001 2012-10 6 2012-10-11
3 I002 2012-09 5 2012-09-15
4 I002 2012-10 4 2012-10-05
5 I004 2012-10 10 2012-10-13
答案 1 :(得分:2)
我假设您示例中的对象是data.frame
,我们称之为df
。
library( "plyr" )
df$rental_date <- as.Date( df$rental_date, "%m/%d/%Y" )
df$year <- as.numeric( format( df$rental_date, "%Y"))
df$month <- months( df$rental_date )
ddply( df, c("item_id", "month", "year"), function(x) {
x[ min(x$rental_date) == x$rental_date, "customer_id", drop=FALSE ]
} )
结果如下:
item_id month year customer_id
1 I001 October 2012 6
2 I001 September 2012 4
3 I002 October 2012 4
4 I002 September 2012 5
5 I004 October 2012 10