【问题标题】:Set column names based on other/previous column names, probably using apply() or a for loop根据其他/以前的列名设置列名,可能使用 apply() 或 for 循环
【发布时间】:2021-10-13 18:49:44
【问题描述】:

我有一个大型数据集,其中每 5 列对应于 1 条动脉的测量值,但只有五列中的第一列被命名。一个例子:


df <- structure(list("agatston", "area", "volume", "density", "mass", 
                     "agatston", "area", "volume", "density", "mass", "agatston", 
                     "area", "volume", "density", "mass"), 
                .Names = c("Artery_1", NA, NA, NA, NA, "Artery_2", NA, NA, NA, NA, "Artery_3", NA, NA, NA, NA), 
                row.names = c(NA, -1L), 
                class = c("tbl_df", "tbl", "data.frame"))

看起来像这样:

df

# A tibble: 1 x 15
  Artery_1 ``    ``     ``      ``    Artery_2 ``    ``     ``      ``    Artery_3 ``    ``     ``      ``   
  <chr>    <chr> <chr>  <chr>   <chr> <chr>    <chr> <chr>  <chr>   <chr> <chr>    <chr> <chr>  <chr>   <chr>
1 agatston area  volume density mass  agatston area  volume density mass  agatston area  volume density mass 

我正在尝试使用 for 循环或 apply() 来使用最新的非缺失列名填充缺失的列名。我想要实现的目标如下所示:

# A tibble: 1 x 15
  Artery_1 Artery_1 Artery_1 Artery_1 Artery_1 Artery_2 Artery_2 Artery_2 Artery_2 Artery_2 Artery_3 Artery_3 Artery_3 Artery_3 Artery_3
  <chr>    <chr>    <chr>    <chr>    <chr>    <chr>    <chr>    <chr>    <chr>    <chr>    <chr>    <chr>    <chr>    <chr>    <chr>   
1 agatston area     volume   density  mass     agatston area     volume   density  mass     agatston area     volume   density  mass 

有什么帮助吗?

编辑: 作为下一步,我想通过将列与它下面的行的名称组合来使列 non_unique,从而产生以下输出:

 # A tibble: 1 x 15
  Artery_1_agatson Artery_1_area Artery_1_volume Artery_1_density Artery_1_mass Artery_2_agatson Artery_2_area Artery_2_volume
  <chr>            <chr>         <chr>           <chr>            <chr>         <chr>            <chr>         <chr>          
1 agatston         area          volume          density          mass          agatston         area          volume         
# ... with 7 more variables: Artery_2_density <chr>, Artery_2_mass <chr>, Artery_3_agatson <chr>, Artery_3_area <chr>,
#   Artery_3_volume <chr>, Artery_3_density <chr>, Artery_3_mass <chr>

【问题讨论】:

    标签: r for-loop dplyr apply


    【解决方案1】:

    基础 R 解决方案:

    names(df) <- paste(
      na.omit(names(df))[cumsum(!(is.na(names(df))))],
      df[1,,drop=TRUE],
      sep = "_"
    )
    

    或者删除第一行:

    clean_df <- setNames(
      df[-1,],
      paste(
        na.omit(names(df))[cumsum(!(is.na(names(df))))],
        df[1,,drop=TRUE],
        sep = "_"
      )
    )
    

    【讨论】:

      【解决方案2】:

      您可以使用zoo::na.locf 替换NA 值。

      names(df) <- zoo::na.locf(names(df))
      names(df)
      
      # [1] "Artery_1" "Artery_1" "Artery_1" "Artery_1" "Artery_1" "Artery_2"
      # [7] "Artery_2" "Artery_2" "Artery_2" "Artery_2" "Artery_3" "Artery_3"
      #[13] "Artery_3" "Artery_3" "Artery_3"```
      

      但是,列名相同不是一个好习惯,因此您可以使用make.unique 使列名唯一。

      names(df) <- make.unique(zoo::na.locf(names(df)))
      names(df)
      
      # [1] "Artery_1"   "Artery_1.1" "Artery_1.2" "Artery_1.3" "Artery_1.4"
      # [6] "Artery_2"   "Artery_2.1" "Artery_2.2" "Artery_2.3" "Artery_2.4"
      #[11] "Artery_3"   "Artery_3.1" "Artery_3.2" "Artery_3.3" "Artery_3.4"
      

      要将列与第一行合并,我们可以使用

      names(df) <- paste(zoo::na.locf(names(df)), df[1, ], sep = '_')
      names(df)
      
      # [1] "Artery_1_agatston" "Artery_1_area"     "Artery_1_volume"  
      # [4] "Artery_1_density"  "Artery_1_mass"     "Artery_2_agatston"
      # [7] "Artery_2_area"     "Artery_2_volume"   "Artery_2_density" 
      #[10] "Artery_2_mass"     "Artery_3_agatston" "Artery_3_area"    
      #[13] "Artery_3_volume"   "Artery_3_density"  "Artery_3_mass"    
      

      然后可能使用df &lt;- df[-1, ] 删除第一行。

      【讨论】:

      • 感谢您的回复。要解决有关非唯一列名的问题:下一步是通过将它们与下面行中的字符串组合使它们唯一。您是否也知道如何实现这一目标?
      • 我已经添加到我原来的问题中,以更清楚地说明我想要实现的目标。
      • 更新后的答案应该可以帮助您做到这一点。
      猜你喜欢
      • 2020-10-31
      • 2019-05-28
      • 1970-01-01
      • 2022-12-03
      • 1970-01-01
      • 2019-07-30
      • 1970-01-01
      • 2019-03-18
      • 2021-08-18
      相关资源
      最近更新 更多