代码之家  ›  专栏  ›  技术社区  ›  Marta López

按条件R将列拆分为多个列

  •  0
  • Marta López  · 技术社区  · 2 年前

    我想根据条件将一列拆分为几列。

    例如,如果字符以P开头,它将转到一列,如果字符以F或C开头,它将转到其他列。

    df <- data.frame(
      "name" = c("a", "b"),
      "ID" = c("P_GO_10;C_GO_23;C_GO_32", "P_GO_65;F_GO15;C_GO_97;F_GO_87"))
    
      name   ID
    1    a P_GO_10;C_GO_23;C_GO_32
    2    b P_GO_65;F_GO15;C_GO_97;F_GO_87
    
    
    
    df_new <- data.frame(
      "name" = c("a", "b"),
      "ID_P" = c("P_GO_10", "P_GO_65"),
      "ID_C" = c("C_GO_23;C_GO_32","C_GO_97"),
      "ID_F" = c(NA, "F_GO_87"))
    
      name ID_P     ID_C               ID_F
    1    a P_GO_10  C_GO_23;C_GO_32    <NA>
    2    b P_GO_65  C_GO_97            F_GO_87
    
    
    0 回复  |  直到 2 年前
        1
  •  0
  •   rg4s    2 年前

    您所要求的结果并不确切,但目前还没有其他答案。

    使用 tidyverse 我们可以这样做:

    df %>% 
      separate_rows(ID, sep = ";") %>% 
      mutate(ID_P = ifelse(grepl("^P", ID), ID, NA),
             ID_C = ifelse(grepl("^C", ID), ID, NA), 
             ID_F = ifelse(grepl("^F", ID), ID, NA)) %>% 
      select(-ID) %>% 
      pivot_longer(-name, names_to = "ID", values_to = "values") %>%
      drop_na() %>% 
      pivot_wider(names_from = ID,
                  values_from = values,
                  values_fn = list, 
                  values_fill = list(values = NA)) 
    
        2
  •  0
  •   jblood94    2 年前

    不是特别优雅的base R解决方案:

    df <- data.frame(
      "name" = c("a", "b"),
      "ID" = c("P_GO_10;C_GO_23;C_GO_32", "P_GO_65;F_GO15;C_GO_97;F_GO_87"))
    
    id2 <- substr(unlist(id1 <- strsplit(df$ID, ";")), 1, 1)
    m <- matrix(NA_character_, nrow(df), length(uid <- unique(id2)))
    m[matrix(c(rep.int(1:nrow(df), lengths(id1)), match(id2, uid)), ncol = 2)] <- unlist(id1)
    cbind(df, setNames(as.data.frame(m), paste0("ID_", uid)))
    #>   name                             ID    ID_P    ID_C    ID_F
    #> 1    a        P_GO_10;C_GO_23;C_GO_32 P_GO_10 C_GO_32    <NA>
    #> 2    b P_GO_65;F_GO15;C_GO_97;F_GO_87 P_GO_65 C_GO_97 F_GO_87