R语言 确定哪个ID没有配对的最有效方法?

cu6pst1q  于 2022-12-20  发布在  其他
关注(0)|答案(2)|浏览(119)

假设我有一个如下所示的 Dataframe 。在该 Dataframe 中,我们有以下ID对(4330,4331)、(2333,2334)、(3336,3337),它们彼此相差+/- 1。但是,3349没有ID对。过滤掉不成对ID的最有效方法是什么?

ID sex zyg race SES
1 4330   2   2    2   1
2 4331   2   2    2   1
3 2333   2   2    1  78
4 2334   2   2    1  78
5 3336   2   2    1  18
6 3337   2   2    1  18
6 3349   2   2    1  18
gjmwrych

gjmwrych1#

这将只返回成对/双胞胎(没有不成对或三胞胎、四胞胎等)。

df <- data.frame(ID = c(1:3, 4330, 4331, 2333, 2334, 3336, 3337, 3349), sex = 2)
df <- df[order(df$ID),]
df[
  rep(
    with(
      rle(diff(df$ID)),
      cumsum(lengths)[lengths == 1L & values == 1]
    ), each = 2
  ) + 0:1,
]
#>     ID sex
#> 6 2333   2
#> 7 2334   2
#> 8 3336   2
#> 9 3337   2
#> 4 4330   2
#> 5 4331   2

说明:
对数据进行排序后,只有组中的个体(双胞胎、三胞胎等)与下一行中的个体的ID差异为1。diff(df$ID)返回整个data.frame中一行与下一行的ID值的差异。要识别双胞胎,我们需要找出diff(df$ID)在何处具有单独的1(即,前一个值和下一个值都不是1)。我们使用rle来找到那些孤立的1

rle(diff(df$ID))
#> Run Length Encoding
#>   lengths: int [1:8] 2 1 1 1 1 1 1 1
#>   values : num [1:8] 1 2330 1 1002 1 12 981 1

当两个diff(df$ID)的值(values)和相同值的游程长度(lengths)都是1。这在第三、第五和第八次运行时发生。(在df内)由cumsum(lengths)给出,因此我们将它们子集在3,5,和8来获得df中每个孪生对的起始索引。我们用rep(..., each = 2)重复这些索引中的每一个两次,然后加上0:1(利用recycling in R)以获得作为双胞胎的任何个体的指数。

dffbzjpn

dffbzjpn2#

使用dplyr::lag()lead(),可以将filter()添加到前一个IDID - 1或下一个IDID + 1的行:

library(dplyr)

df %>% 
  filter(lag(ID) == ID - 1 | lead(ID) == ID + 1)
# A tibble: 6 × 5
     ID   sex   zyg  race   SES
  <dbl> <dbl> <dbl> <dbl> <dbl>
1  4330     2     2     2     1
2  4331     2     2     2     1
3  2333     2     2     1    78
4  2334     2     2     1    78
5  3336     2     2     1    18
6  3337     2     2     1    18
  • edit,这将 * 不会 * 过滤掉"三胞胎"、"四胞胎"等,这与注解中提到的附加要求相反。

相关问题