我有一个简单的目标,我希望在我的数据框中实现这样的目标:
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行
答案 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))