有没有办法在数据集中删除具有相反符号的对?

时间:2016-11-16 23:11:50

标签: r dplyr

我有一个数据集如下。如果取消是" Y"然后美元是负面的,反之亦然。
 根据数据,我想在同一个id中删除具有相同的美元但不同符号(当然应该有取消值的不同符号)的对。

DF

rownumber id1    cancel      dollar 
    1       1      Y          -50     
    2       1      N           10     
    3       1      N           50     
    4       2      N           14.4     
    5       2      Y          -23.5     
    6       2      N           23.5     
    7       3      Y          -15.5     
    8       3      N           15.5   
    9       4      Y           -20.5

因此,这是我想要的输出。

df_desired

rownumber id1    cancel      dollar 
    2       1      N           10     
    4       2      N           14.4     
    9       4      Y           -20.5

也许,我可以通过使用for循环来做到这一点但是数据太大而无法做到。
有什么简单的方法吗?

4 个答案:

答案 0 :(得分:1)

由于iff cancel = Y有负号,为什么不简单地将绝对值存储在dollar?然后,您可以获取具有取消+美元的唯一值的行。过滤后,如果需要,可以添加负号。

如果由于某种原因这不是一个选项,如果你有足够的内存来构建数据中的hashset,你仍然可以在O(2)时间内完成它:对于每一行,将dollar插入到一个hashset中。然后再次迭代并过滤掉hashset包含-dollar的所有值。

答案 1 :(得分:1)

正如@ Eric.M所说,你可以通过在取dollar的绝对值后查找重复的行来做到这一点:

df[with(df, ave(rownumber, list(id1, abs(dollar)), FUN=length)==1 ),]
#  rownumber id1 cancel dollar
#2         2   1      N   10.0
#4         4   2      N   14.4
#9         9   4      Y  -20.5

答案 2 :(得分:1)

你可以这样做:

v <- unlist(aggregate(dollar~id1, df, 
              function(x) !(duplicated(abs(x)) | duplicated(abs(x), fromLast = T)))$dollar)
df[which(v),]

#  rownumber id1 cancel dollar
#2         2   1      N   10.0
#4         4   2      N   14.4
#9         9   4      Y  -20.5
!(duplicated(abs(x)) | duplicated(abs(x), fromLast = T))使用id1进行分组后,

aggregate完全符合您的要求。

OR

(感谢@thelatemail指出这一点):

tmp <- interaction(df$id1, abs(df$dollar))
df[!(duplicated(tmp) | duplicated(tmp, fromLast = T)),]

答案 3 :(得分:0)

因为您标记了dplyr,我们可以像这样使用dplyr

df %>% group_by(id1, abs(dollar)) %>% filter(sum(dollar) != 0)

  rownumber   id1 cancel dollar `abs(dollar)`
      <int> <int>  <chr>  <dbl>         <dbl>
1         2     1      N   10.0          10.0
2         4     2      N   14.4          14.4
3         9     4      Y  -20.5          20.5

如果旧版分组abs_dollar列分散注意力%>% ungroup() %>% select(-5)