我有一个包含大量条目的数据集。这些条目中的每一个都属于某个ID(属于ID),条目是唯一的(具有uniqID),但是多个条目可以来自同一个源(sourceID)。来自同一源的多个条目也可能具有相同的属性ID。出于研究的目的,我需要对数据集进行处理,我必须删除单个sourceID的条目,该条目对于1个belongsID发生超过5次。需要保留的最多5个条目是具有最高“时间”值的条目。
为了说明这一点,我有以下示例数据集:
belongID sourceID uniqID Time
1 1001 101 5
1 1002 102 5
1 1001 103 4
1 1001 104 3
1 1001 105 3
1 1005 106 2
1 1001 107 2
1 1001 108 2
2 1005 109 5
2 1006 110 5
2 1005 111 5
2 1006 112 5
2 1005 113 5
2 1006 114 4
2 1005 115 4
2 1006 116 3
2 1005 117 3
2 1006 118 3
2 1005 119 2
2 1006 120 2
2 1005 121 1
2 1007 122 1
3 1010 123 5
3 1480 124 2
最后的例子应如下所示:
belongID sourceID uniqID Time
1 1001 101 5
1 1002 102 5
1 1001 103 4
1 1001 104 3
1 1001 105 3
1 1005 106 2
1 1001 107 2
2 1005 109 5
2 1006 110 5
2 1005 111 5
2 1006 112 5
2 1005 113 5
2 1006 114 4
2 1005 115 4
2 1006 116 3
2 1005 117 3
2 1006 118 3
2 1007 122 1
3 1010 123 5
3 1480 124 2
文件中有更多包含数据条目的列,但选择必须完全基于时间。如示例所示,还可能发生具有相同belongsID的sourceID的第5和第6个条目具有相同的时间。在这种情况下,只需要选择1,因为max = 5。
为了便于说明,此处的数据集在belongsID和时间上排序很好,但在真实数据集中并非如此。知道如何解决这个问题吗?我还没有遇到类似的东西..
答案 0 :(得分:1)
假设您的数据位于df
。在此之后获得有序(通过uniqID)输出:
tab <- tapply(df$Time, list(df$belongID, df$sourceID), length)
bIDs <- rownames(tab)
sIDs <- colnames(tab)
for(i in bIDs)
{
if(all(is.na(tab[bIDs == i, ])))next
ids <- na.omit(sIDs[tab[i, sIDs] > 5])
for(j in ids)
{
cond <- df$belongID == i & df$sourceID == j
old <- df[cond,]
id5 <- order(old$Time, decreasing = TRUE)[1:5]
new <- old[id5,]
df <- df[!cond,]
df <- rbind(df, new)
}
}
df[order(df$uniqID), ]
答案 1 :(得分:1)
使用plyr
包的两行解决方案:
library(plyr)
x <- ddply(dat, .(belongID, sourceID), function(x)tail(x[order(x$Time), ], 5))
xx <- x[order(x$belongID, x$uniqID), ]
结果:
belongID sourceID uniqID Time
5 1 1001 101 5
6 1 1002 102 5
4 1 1001 103 4
2 1 1001 104 3
3 1 1001 105 3
7 1 1005 106 2
1 1 1001 108 2
10 2 1005 109 5
16 2 1006 110 5
11 2 1005 111 5
17 2 1006 112 5
12 2 1005 113 5
15 2 1006 114 4
9 2 1005 115 4
13 2 1006 116 3
8 2 1005 117 3
14 2 1006 118 3
18 2 1007 122 1
19 3 1010 123 5
20 3 1480 124 2
答案 2 :(得分:1)
如果dat
是您的数据框:
do.call(rbind,
by(dat, INDICES=list(dat$belongID, dat$sourceID),
FUN=function(x) head(x[order(x$Time, decreasing=TRUE), ], 5)))
答案 3 :(得分:0)
将使用此方法的数据集包含170.000+条目和近30列
使用我的数据集对danas.zuokas,mplourde和Andrie提供的三个解决方案中的每一个进行基准测试,提供了以下结果:
danas.zuokas'解决方案:
User System Elapsed
2829.569 0 2827.86
mplourde的解决方案:
User System Elapsed
765.628 0.000 763.908
Aurdie的解决方案:
User System Elapsed
984.989 0.000 984.010
因此我将使用mplourde的解决方案。谢谢大家!
答案 4 :(得分:0)
这应该更快,使用data.table
:
DT = as.data.table(dat)
DT[, .SD[tail(order(Time),5)], by=list(belongID, sourceID)]
除此之外:建议计算在此问题的各种答案中重复相同变量名称的次数。你有很多长或类似的对象名称吗?