【问题标题】:Insert dots in column names in wide data using R使用 R 在宽数据中的列名中插入点
【发布时间】:2020-12-27 02:48:54
【问题描述】:

以下数据集为宽格式,有“ql”、“st”、“xy”前缀“a”、“b”、“c”的重复测量;

df<-data.frame(id=c(1,2,3,4),
               ex=c(1,0,0,1),
               aql=c(5,4,NA,6),
               bql=c(5,7,NA,9),
               cql=c(5,7,NA,9),
               bst=c(3,7,8,9),
               cst=c(8,7,5,3),
               axy=c(1,9,4,4),
               cxy=c(5,3,1,4))

我正在寻找一种在前缀字母“a”、“b”和“c”之后插入点的方法,同时保持其他列(即 id、ex)不变。我一直在使用 gsub 函数解决这个问题,例如

names(df) <- gsub("", "\\.", names(df))

但得到了不希望的结果。预期的输出看起来像

   id ex a.ql b.ql c.ql b.st c.st a.xy c.xy
1  1  1    5    5    5    3    8    1    5
2  2  0    4    7    7    7    7    9    3
3  3  0   NA   NA   NA    8    5    4    1
4  4  1    6    9    9    9    3    4    4

【问题讨论】:

  • 试试sub("(^[a-c])(.+)", "\\1.\\2", names(df))

标签: r dataframe rename gsub


【解决方案1】:

你可以尝试另一种方式

library(dplyr)
df %>% 
  rename_at(vars(aql:cxy), ~ str_replace(., "(?<=\\w{1})", "\\."))
#   id ex a.ql b.ql c.ql b.st c.st a.xy c.xy
# 1  1  1    5    5    5    3    8    1    5
# 2  2  0    4    7    7    7    7    9    3
# 3  3  0   NA   NA   NA    8    5    4    1
# 4  4  1    6    9    9    9    3    4    4

【讨论】:

    【解决方案2】:

    试试

    sub("(^[a-c])(.+)", "\\1.\\2", names(df))
    
    # [1] "id"   "ex"   "a.ql" "b.ql" "c.ql" "b.st" "c.st" "a.xy" "c.xy"
    

    sub("(?<=^[a-c])", ".", names(df), perl = TRUE)
    
    # [1] "id"   "ex"   "a.ql" "b.ql" "c.ql" "b.st" "c.st" "a.xy" "c.xy"
    

    【讨论】:

    • (.+) 仅在我们需要确保输入中至少有两个字符时才需要。如果没有必要,只需使用sub("^([a-c])", "\\1.", names(df))
    【解决方案3】:

    你可以的

    setNames(df, sub("(ql$)|(st$)|(xy$)", "\\.\\1\\2\\3", names(df)))
    
    #>   id ex a.ql b.ql c.ql b.st c.st a.xy c.xy
    #> 1  1  1    5    5    5    3    8    1    5
    #> 2  2  0    4    7    7    7    7    9    3
    #> 3  3  0   NA   NA   NA    8    5    4    1
    #> 4  4  1    6    9    9    9    3    4    4
    

    【讨论】:

      【解决方案4】:

      您也可以尝试使用tidyverse 方法来重塑您的数据,如下所示:

      library(tidyverse)
      #Data
      df<-data.frame(id=c(1,2,3,4),
                     ex=c(1,0,0,1),
                     aql=c(5,4,NA,6),
                     bql=c(5,7,NA,9),
                     cql=c(5,7,NA,9),
                     bst=c(3,7,8,9),
                     cst=c(8,7,5,3),
                     axy=c(1,9,4,4),
                     cxy=c(5,3,1,4))
      #Reshape
      df %>% pivot_longer(-c(1,2)) %>%
        mutate(name=paste0(substring(name,1,1),'.',substring(name,2,nchar(name)))) %>%
        pivot_wider(names_from = name,values_from=value)
      

      输出:

      # A tibble: 4 x 9
           id    ex  a.ql  b.ql  c.ql  b.st  c.st  a.xy  c.xy
        <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
      1     1     1     5     5     5     3     8     1     5
      2     2     0     4     7     7     7     7     9     3
      3     3     0    NA    NA    NA     8     5     4     1
      4     4     1     6     9     9     9     3     4     4
      

      【讨论】:

        猜你喜欢
        • 2023-03-11
        • 2012-04-08
        • 1970-01-01
        • 2020-12-26
        • 1970-01-01
        • 2023-02-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-30
        相关资源
        最近更新 更多