【问题标题】:Use pivot_longer to cast data to long with repeated column names使用 pivot_longer 将数据转换为具有重复列名的 long
【发布时间】:2023-03-13 07:10:02
【问题描述】:

我有一个无限长的df。下面的示例只有 2 个特征:“密度”和“脂质”,但其他 dfs 可能有 50 个或更多特征。每个 trait 都有 3 列与之关联:value.trait、unit.trait、method.trait。 Seems very similiar to this example in vignette 但是当我运行下面的代码时,我不断收到错误:输入必须是向量,而不是 NULL

3行样本数据

 x <- structure(list(geno_name = c("MB mixed", "MB mixed", "MB mixed"
), study_location = c("lab", "lab", "lab"), author = c("test", 
"test", "test"), value.lipids = c(NA, 2.361463603, 1.461189384
), unit.lipids = c(NA, "g cm^-2", "g cm^-2"), method.lipids = c(NA, 
"airbrush", "airbrush"), value.density = c(1.125257337, 0.816034359, 
0.49559013), unit.density = c("g cm^-3", "g cm^-3", "g cm^-3"
), method.density = c("3D scanning", "3D scanning", "3D scanning"
)), row.names = c(NA, 3L), class = "data.frame")

当前枢轴代码:

x %>%
  select(!c(study_location, author)) %>%
  pivot_longer(cols = !geno_name,
               names_to = c(".value", "trait"),
               names_sep = ".",
               values_drop_na = TRUE)

错误代码:

错误:输入必须是向量,而不是 NULL。运行rlang::last_error() 到 查看错误发生的位置。另外:警告信息:1:在 gsub(paste0("^", names_prefix), "", names(cols)) : 参数 'pattern' 的长度 > 1 并且仅使用第一个元素 2: 预计2件。在 6 行 [1, 2, 3, 4, 5, 6]。

【问题讨论】:

标签: r


【解决方案1】:

我们也可以

tidyr::pivot_longer(x, 
         cols = c(lipids, density), 
         names_to = c('.value', 'trait'), 
         names_sep = '[.]', 
         values_drop_na = TRUE)

【讨论】:

    【解决方案2】:

    这是一种方法,它首先使数据更长,然后从单元/方法中分离出特征,然后传播这些特征。

    x %>% 
      janitor::clean_names() %>%    # This makes the column names distinct with #s
      pivot_longer(cols = -(1:2),
                   names_to = "var",
                   values_to = "val", 
                   values_transform = list(val = as.character)) %>%
      mutate(trait = if_else(str_detect(var, "unit|method", negate = TRUE),
                             var, NA_character_),
             # the regex below is meant to remove everything starting with _
             stat = if_else(is.na(trait), var %>% str_remove("\\_[^.]*$"), "value")) %>%
      fill(trait) %>%
      select(-var) %>%
      pivot_wider(names_from = stat, values_from = val)
    
    # A tibble: 2 x 6
      geno_name observation_id trait   value  unit    method     
      <chr>              <dbl> <chr>   <chr>  <chr>   <chr>      
    1 MB mixed              10 lipids  NA     NA      NA         
    2 MB mixed              10 density 1.125  g cm^-3 3D scanning
    

    【讨论】:

      【解决方案3】:

      您可以将pivot_longer 用作:

      tidyr::pivot_longer(x, 
                   cols = matches('lipids|density'), 
                   names_to = c('.value', 'trait'), 
                   names_sep = '\\.', 
                   values_drop_na = TRUE)
      
      #  geno_name study_location author trait   value unit    method     
      #  <chr>     <chr>          <chr>  <chr>   <dbl> <chr>   <chr>      
      #1 MB mixed  lab            test   density 1.13  g cm^-3 3D scanning
      #2 MB mixed  lab            test   lipids  2.36  g cm^-2 airbrush   
      #3 MB mixed  lab            test   density 0.816 g cm^-3 3D scanning
      #4 MB mixed  lab            test   lipids  1.46  g cm^-2 airbrush   
      #5 MB mixed  lab            test   density 0.496 g cm^-3 3D scanning
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-05-31
        • 2021-07-26
        • 1970-01-01
        • 2018-04-07
        • 1970-01-01
        • 1970-01-01
        • 2020-07-14
        相关资源
        最近更新 更多