删除数据框中重复的 TIME 点

Delete repeated TIME points in a 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

我如何为唯一 TIME 的 df 子集(即摆脱具有 AMT=0 的重复时间点?为了更清楚:我想删除具有 AMT 的重复 TIME 行=0.

你问的不是很清楚。我想你想要的是,对于每个唯一的 ID 值,消除重复的 TIME 行,如果重复的行具有 AMT=0,则更愿意删除该行而不是另一个具有 AMT!=0 的重复行(具有相同的 TIME 值) .

执行此操作的最佳方法实际上是调用组中所有重复项中所有 AMT 值的 aggregate(), and group by both ID and TIME, taking the 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

从描述中还​​不完全清楚我们要如何删除重复的元素。假设 '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))