删除数据框中的重复TIME点

时间:2015-04-08 03:25:41

标签: r dataframe

我有一个简单的目标,我希望在我的数据框中实现这样的目标:

ID  TIME  AMT   
1    0    100    
1    1     0     
1    2     0     
1    2     50
1    3     0
2    0     50
2    1     0     
2    2     0     
2    2     100
2    3     0

如何将df用于唯一TIME的子集(即删除具有AMT=0的重复时间点?为了使其更清晰:我想删除具有AMT = 0的重复TIME行

2 个答案:

答案 0 :(得分:3)

你所要求的并不完全清楚。我想你想要的是,对于每个唯一的ID值,消除重复的TIME行,如果重复的行具有AMT = 0,则更喜欢删除该行而不是具有AMT的另一个副本(具有相同的TIME值)!= 0

实现此目的的最佳方法实际上是调用aggregate(),并按ID和TIME进行分组,获取组中所有重复项中所有AMT值的max()(因此这将是适用于具有两行以上的重复组(如果存在):

df <- data.frame(id=c(1,1,1,1,1,2,2,2,2,2), time=c(0,1,2,2,3,0,1,2,2,3), amt=c(100,0,0,50,0,50,0,0,100,0) );
df;
##    id time amt
## 1   1    0 100
## 2   1    1   0
## 3   1    2   0
## 4   1    2  50
## 5   1    3   0
## 6   2    0  50
## 7   2    1   0
## 8   2    2   0
## 9   2    2 100
## 10  2    3   0
aggregate(amt~id+time, df, max );
##   id time amt
## 1  1    0 100
## 2  2    0  50
## 3  1    1   0
## 4  2    1   0
## 5  1    2  50
## 6  2    2 100
## 7  1    3   0
## 8  2    3   0

正如你所看到的,订单有点混乱,但你可以通过以后调用order()轻松解决这个问题:

df2 <- aggregate(amt~id+time, df, max );
df2[order(df2$id,df2$time),];
##   id time amt
## 1  1    0 100
## 3  1    1   0
## 5  1    2  50
## 7  1    3   0
## 2  2    0  50
## 4  2    1   0
## 6  2    2 100
## 8  2    3   0

答案 1 :(得分:1)

从描述中不完全清楚,我们如何删除重复的元素。假设'TIME','ID'有重复,但'AMT'元素既不是零也不是最大值。如果我们只需要删除每个组合的'0'值,

library(data.table)
res1 <- setDT(df1)[, if(all(AMT==0)) .SD[1L] else .SD[AMT!=0], list(TIME,ID)]
res1[order(TIME)]
#   TIME ID AMT
#1:    0  1 100
#2:    0  2  50
#3:    1  1   0
#4:    1  2   0
#5:    2  1  50
#6:    2  2 100
#7:    3  1   0
#8:    3  2   0

或者如果删除重复项的想法是@bgoldst所假设的,则使用data.table的等效选项是

 res2 <- setDT(df1)[, list(amt=max(AMT)), list(TIME, ID)]
 res2[order(TIME)]
 #   TIME ID amt
 #1:    0  1 100
 #2:    0  2  50
 #3:    1  1   0
 #4:    1  2   0
 #5:    2  1  50
 #6:    2  2 100
 #7:    3  1   0
 #8:    3  2   0

数据

df1 <- structure(list(ID = c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L), 
TIME = c(0L, 1L, 2L, 2L, 3L, 0L, 1L, 2L, 2L, 3L), AMT = c(100L, 
0L, 0L, 50L, 0L, 50L, 0L, 0L, 100L, 0L)), .Names = c("ID", 
"TIME", "AMT"), class = "data.frame", row.names = c(NA, -10L))