代码之家  ›  专栏  ›  技术社区  ›  Kevin Sun

如何在R中填充按重复ID分组的各个列的NAS

  •  0
  • Kevin Sun  · 技术社区  · 6 年前

    我有一张有柱子的桌子 id , colA colB . 数据包含重复的ID列,其中某些行, 可乐 科尔布 为空,但它是重复的 身份证件 具有有效值。我想清除数据,以便删除重复项,但有完整的数据。例如,我的数据看起来像

    id | colA | colB
     1     NA    X
     1      Y    X
     2      Z    NA
     2      Z    Y
     3      Z    Y
     3      Z    Y
     4     NA    NA
     4     NA    NA
    

    我希望我的数据框架看起来像

    id | colA | colB
    1     Y      X
    2     Z      Y
    3     Z      Y
    4     NA     NA
    

    我通常用 ifelse 语句来替换缺少的值,但我对如何在重复的上下文中使用它感到困惑 身份证件 S.

    3 回复  |  直到 6 年前
        1
  •  2
  •   neilfws    6 年前

    这个答案非常依赖于您的实际数据在结构上与示例数据相似。

    你的数据:

    df1 <- structure(list(id = c(1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L), 
                          colA = c(NA, "Y", "Z", "Z", "Z", "Z", NA, NA), 
                          colB = c("X", "X", NA, "Y", "Y", "Y", NA, NA)), 
                          class = "data.frame", 
                          row.names = c(NA, -8L))
    

    假设,如您的示例中,每个 id 发生两次,其中一次观察 NA 这是第一次观察到 身份证件 ,那么这就工作了:

    library(dplyr)
    library(tidyr)
    
    df1 %>% 
      group_by(id) %>% 
      fill(colA, colB, .direction = "up") %>%  
      ungroup() %>% 
      distinct()
    
    # A tibble: 4 x 3
         id colA  colB 
      <int> <chr> <chr>
    1     1 Y     X    
    2     2 Z     Y    
    3     3 Z     Y    
    4     4 NA    NA 
    

    如果第二次观察 身份证件 可以是 ,您可以尝试添加一秒钟 fill 在第一个之后,但这次请填写:

    df1 %>% 
      group_by(id) %>% 
      fill(colA, colB, .direction = "up") %>%  
      fill(colA, colB, .direction = "down") %>%  
      ungroup() %>% 
      distinct()
    
        2
  •  4
  •   Shree    6 年前

    首先添加一列,告诉您 NA 在每一行。然后使用 dplyr ,首先删除重复的行,然后为每个ID保留丢失值最少的行。-

    df$test <- rowSums(is.na(df))
    
    df %>% 
      filter(!duplicated(.)) %>% 
      arrange(id, test) %>% 
      group_by(id) %>% 
      filter(row_number() == 1) %>% 
      ungroup() %>% 
      select(-test)
    
    # A tibble: 4 x 3
         id colA  colB 
      <int> <chr> <chr>
    1     1 y     x    
    2     2 z     y    
    3     3 z     y    
    4     4 <NA>  <NA> 
    

    编辑: 实际上,不需要先删除重复项。只保留每个ID值最少的行也应该有效。-

    df$test <- rowSums(is.na(df))
    
    df %>% 
      arrange(id, test) %>% 
      group_by(id) %>% 
      filter(row_number() == 1) %>% 
      ungroup() %>% 
      select(-test)
    

    数据-

    df <- data.frame(
      id = c(rep(seq(1:4), each =2)), colA = c(NA, "y", "z", "z", "z", "z", NA, NA), 
      colB = c("x", "x", NA, "y", "y", "y", NA, NA), stringsAsFactors = F)
    
        3
  •  1
  •   André.B    6 年前

    创建数据框架-如果您发布代码以生成示例数据,它将有所帮助

    df <- data.frame(id = c(rep(seq(1:4), each =2)), colA = c(NA, "y", "z", "z", "z", "z", NA, NA), colB = c("x", "x", NA, "y", "y", "y", NA, NA))
    

    删除带有单个NAS的行

    for(i in 1:nrow(df)){
    
      if(is.na(df[i,]$colA) & !is.na(df[i,]$colB) | !is.na(df[i,]$colA) & is.na(df[i,]$colB)){
    
    df <- df[-i,]
    
      }
    }
    

    删除剩余的重复项(即双NA行)

    df  <- df[!duplicated(df), ]
    

    产量

    df
    

    这可能是一种更有效的计算方法,但这应该是可行的。