我有一个250万行的数据框(df)。示例数据框如下所示:
PERMNO <- c(10000,10000,10001,10001,10001,10001, 10002,10002,10002)
TICKER <- c('OMFGA','OMFGA', 'GFGC', 'GFGC', 'GFGC', 'GFGC', 'MBNC', 'MBNC', 'MBNC')
date <- as.Date(c('1986-03-31','1986-04-30','1986-01-31', '1986-01-31', '1986-03-31', '1986-04-30', '1986-04-30','1986-05-30', '1986-05-30'))
df = data.frame(PERMNO, date, TICKER)
在这个例子中,有3个独特的PERMNO。现在我需要提取给定PERMNO的所有数据,并检查是否有任何重复日期。我的目的是删除具有特定PERMNO的重复日期的行。我为所有独特的PERMNO做了这个操作
我的方法:我使用子集函数来提取特定PERMNO的数据,然后检查日期中的重复项。但是使用这种方法,我的代码每次都会遍历整个数据(原始数据集中有250万行),以便为特定的PERMNO提取数据。有没有更短的方法来做到这一点?由于我有22000个唯一的PERMNO,因此代码将永远在For循环中运行。
以下是我使用的代码:
uniqueperm = unique(df$PERMNO)
lenperm = length(uniqueperm)
data_final = df[FALSE,]
for(i in 1:lenperm){
perm = uniqueperm[i]
df1 = filter(df, PERMNO == perm)
df1 = subset(df1,!duplicated(df1$date))
data_final = rbind(data_final,df1)
df1 = df1[FALSE,]
}
data_final
答案 0 :(得分:3)
除了大量数据集外,这应该相当快:
df[!duplicated(df[c("PERMNO","date")]),]
# PERMNO date TICKER
#1 10000 1986-03-31 OMFGA
#2 10000 1986-04-30 OMFGA
#3 10001 1986-01-31 GFGC
#5 10001 1986-03-31 GFGC
#6 10001 1986-04-30 GFGC
#7 10002 1986-04-30 MBNC
#8 10002 1986-05-30 MBNC
与您拥有的类似数据的基本时间:
df2 <- data.frame(PERMNO=sample(1:22000,2.5e6,replace=TRUE), date=1:2.5e6)
nrow(df2)
#[1] 2500000
length(unique(df2$PERMNO))
#[1] 22000
system.time(df2[!duplicated(df2[c("PERMNO","date")]),])
# user system elapsed
# 3.48 0.08 3.56
答案 1 :(得分:1)
这应该比大数据集的for循环更快:
dates <- lapply(split(df, df$PERMNO), '[[', "date")
df2 <-mapply(function(x,y)x[!y,],
split(df,df$PERMNO),
lapply(dates, duplicated),
SIMPLIFY = FALSE)
do.call(rbind, df2)
# PERMNO date TICKER
# 10000.1 10000 1986-03-31 OMFGA
# 10000.2 10000 1986-04-30 OMFGA
# 10001.3 10001 1986-01-31 GFGC
# 10001.5 10001 1986-03-31 GFGC
# 10001.6 10001 1986-04-30 GFGC
# 10002.7 10002 1986-04-30 MBNC
# 10002.8 10002 1986-05-30 MBNC