R - 根据参考值更改值

时间:2016-03-29 17:58:19

标签: r

我的数据框看起来像这个玩具示例:

Ind     ID    RegionStart     RegionEnd    Value     TN
1       A       1              100           3       N
1       A       101            200           2       N
2       A       1              100           3       T
2       A       101            200           2       T
3       B       1              100           3       N
3       B       101            200           2       N
4       B       1              100           5       T
4       B       101            200           5       T

我有4个人,实际上是2对(参考,N和主题,T)。为简单起见,只有2对,只有2个区域。在我的真实文件中,有> 500对和> 60,000个区域。这些区域都有相同的开始和结束,因此没有重叠。

我想做的是根据ID + region匹配个人,如果

  • 该区域的N个体的Value是!= 3(不等于3)&
  • N-individual&的Value该区域中的T-个体匹配(例如,N-ind = 2& T-ind = 2),

然后在N&中更改相应的Value T个人到3。

上面的结果表是:

Ind     ID    RegionStart     RegionEnd    Value     TN
1       A       1              100           3       N
1       A       101            200           3       N
2       A       1              100           3       T
2       A       101            200           3       T
3       B       1              100           3       N
3       B       101            200           2       N
4       B       1              100           5       T
4       B       101            200           5       T

请注意,ID=B,地区1-100未更改Value,因为N' Value = 3;区域101-200,因为N& Value而没有变化T不一样。

我想过使用dplyr对匹配进行分组,例如:

df <- df %>% arrange(ID, Ind, RegionStart, TN) %>% group_by(ID)

或者也许使用data.table,但设置ID作为键?但我还是不确定如何轻松比较行。我对dplyr&amp; data.table,所以如果使用这些命令,那么命令的简短说明会很棒。不过,请随意使用其他包装。但数据非常大,因此需要高效。

1 个答案:

答案 0 :(得分:4)

使用data.table:

library(data.table)
setDT(DF)

DF[, Value := { 
  fixit = ( Value[TN=="N"] != 3L ) & ( uniqueN(Value) == 1L )
  if (fixit) 3L else Value
}, by=.(ID, RegionStart)]

请注意,这将更改原始数据集(而不是简单地返回更改的表格)。

使用dplyr:

library(dplyr)
DF %>% group_by(ID, RegionStart) %>% 
  mutate(Value = {
    fixit = ( Value[TN=="N"] != 3L ) & ( n_distinct(Value) == 1L )
    if (fixit) 3L else Value
  })

工作原理: uniqueNn_distinct计算向量中不同值的数量。如果Value的两个元素相同,则返回1L