删除数据框中重复的 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))
我想在我的数据框中实现一个简单的目标,如下所示:
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))