代码之家  ›  专栏  ›  技术社区  ›  giac

不同行中匹配的成对id上的向量

  •  -1
  • giac  · 技术社区  · 6 年前

    我想创建一个向量来标识具有匹配标识符的行。例如, hldid 是家庭识别码, persid 个人识别码和 partner id 匹配的标识符。

    我想创建一个向量 couple 什么时候 珀西德 有一个 partner .

           hldid persid partner_id age sex child
    1     243312      2         91  20   2     0
    2     243312     91          2  29   1     0
    3     103340      0          0   6   1     2
    4     103340      2         91  39   2     2
    5     103340      4          0  14   2     2
    6     103340     91          2  42   1     2
    7    1105347      2          0  25   2     2
    8    1105347      3          3  50   2     2
    9    1105347     91          0  25   1     2
    10 110322323      3          0  15   2     1
    11 110322323     10          0  15   2     1
    

    这会给

           hldid persid partner_id age sex child couple
    1     243312      2         91  20   2     0      1
    2     243312     91          2  29   1     0      1
    3     103340      0          0   6   1     2      0
    4     103340      2         91  39   2     2      1
    5     103340      4          0  14   2     2      0
    6     103340     91          2  42   1     2      1
    7    1105347      2          0  25   2     2      0 
    8    1105347      3          3  50   2     2      0
    9    1105347     91          0  25   1     2      0
    10 110322323      3          0  15   2     1      0
    11 110322323     10          0  15   2     1      0
    

    我创造了一个 loop

    df$couple = 0
    
     for(i in 1:nrow(df)){
        if(
          df$hldid[i] == df$hldid[i+1] &
        (df$persid[i] == df$partner_id[i+1])
        )
        {
          df$couple[i] = 1
          df$couple[i+1] = 1
        }
      }
    }
    

    但是,当标识符彼此不相邻时,它无法正常工作。

    df = structure(list(hldid = c(243312L, 243312L, 103340L, 103340L, 
    103340L, 103340L, 1105347L, 1105347L, 1105347L, 110322323L, 110322323L
    ), persid = c(2L, 91L, 0L, 2L, 4L, 91L, 2L, 3L, 91L, 3L, 10L), 
    partner_id = c(91, 2, 0, 91, 0, 2, 0, 3, 0, 0, 0), age = c(20L, 
    29L, 6L, 39L, 14L, 42L, 25L, 50L, 25L, 15L, 15L), sex = c(2L, 
    1L, 1L, 2L, 2L, 1L, 2L, 2L, 1L, 2L, 2L), child = c(0, 0, 
    2, 2, 2, 2, 2, 2, 2, 1, 1)), class = "data.frame", row.names = c(NA, 
    -11L), .internal.selfref = <pointer: 0x10280b2e0>)
    
    3 回复  |  直到 6 年前
        1
  •  1
  •   Gregor Thomas    6 年前

    我认为问题是你没有考虑到 couple 手段。看你想要的结果,在我看来任何一行 partner_id 不等于0 persid 获取1,所有其他行获取0。这是一个简单的条件,而且很容易实现:

    df$couple = with(df, ifelse(partner_id != 0 & partner_id != persid, 1, 0))
    
        2
  •  0
  •   Andre Elrico    6 年前

    用普通的R基,

    tmp  <- df1[,c("persid", "partner_id")]
    tmp2 <- t(apply(tmp, 1, sort))
    tmp2 <- unique( tmp2[duplicated(tmp2),] )
    
    df1$couple <-
    as.integer(apply( tmp, 1, function(x) { all(x %in% tmp2)}))
    

    #       hldid persid partner_id age sex child couple
    #1     243312      2         91  20   2     0      1
    #2     243312     91          2  29   1     0      1
    #3     103340      0          0   6   1     2      0
    #4     103340      2         91  39   2     2      1
    #5     103340      4          0  14   2     2      0
    #6     103340     91          2  42   1     2      1
    #7    1105347      2          0  25   2     2      0
    #8    1105347      3          3  50   2     2      0
    #9    1105347     91          0  25   1     2      0
    #10 110322323      3          0  15   2     1      0
    #11 110322323     10          0  15   2     1      0
    
        3
  •  0
  •   zack    6 年前

    根据@gregor的评论,我不完全确定我是否遵循了合作伙伴需要连续排成一行的逻辑。对我来说,这似乎可以通过一个连接来解决:

    library(data.table)
    setDT(df)
    merge(df, df, by = )
    
    df[df,
       .(i.hldid, i.persid, i.partner_id, i.age, i.sex, i.child,
         couple = ifelse(is.na(child) | i.partner_id == 0 | i.partner_id == i.persid, 0, 1)),
       on = c("hldid", "persid==partner_id")]
    
          i.hldid i.persid i.partner_id i.age i.sex i.child couple
     1:    243312        2           91    20     2       0      1
     2:    243312       91            2    29     1       0      1
     3:    103340        0            0     6     1       2      0
     4:    103340        2           91    39     2       2      1
     5:    103340        4            0    14     2       2      0
     6:    103340       91            2    42     1       2      1
     7:   1105347        2            0    25     2       2      0
     8:   1105347        3            3    50     2       2      0
     9:   1105347       91            0    25     1       2      0
    10: 110322323        3            0    15     2       1      0
    11: 110322323       10            0    15     2       1      0