22

我有大量数据集,每个数据集都包含一长串列名。在某些文件中,列名都是大写字母,而在某些文件中,只有列名的第一个字母大写。我需要附加数据集,并认为在数据集中匹配列名的最简单方法是将全大写名称转换为仅首字母大写的名称。

我希望找到一个通用的解决方案,甚至可能是单线。

这是我的示例数据集。所需的名称包含在names语句中。

my.data2 <-  "
landuse units grade CLAY    LINCOLN  BASINANDRANGE  MCCARTNEY  MAPLE
apple   acres AAA     0         2          3             4         6
apple   acres AA   1000       900         NA            NA       700
pear    acres AA   10.0        20         NA          30.0        40
peach   acres AAA   500       400        350           300       200
"
my.data2 <- read.table(textConnection(my.data2), header=TRUE)

names(my.data2)[names(my.data2)=="CLAY"]            <- "Clay"
names(my.data2)[names(my.data2)=="BASINANDRANGE"]   <- "BasinandRange"
names(my.data2)[names(my.data2)=="LINCOLN"]         <- "Lincoln"
names(my.data2)[names(my.data2)=="MCCARTNEY"]       <- "McCartney"
names(my.data2)[names(my.data2)=="MAPLE"]           <- "Maple"

my.data2

请注意,我包括了名称McCartneyBasinandRange并使事情变得更现实和更困难。但是,如果我能找到一个单行代码来处理 95% 的名称,并使用上述names语句来处理诸如McCartney和之类的复杂情况BasinandRange,那就太好了。

我搜索了互联网,包括 StackOverflow 档案,但没有找到解决方案。对不起,如果我忽略了一个。感谢您的任何帮助。

4

9 回答 9

39

这是我能想到的实现“在数据集中匹配列名的最简单方法”的单行代码:

## Columns 1:3 left unaltered since they are not place names.
names(my.data2)[-1:-3] <- tolower(names(my.data2)[-1:-3])

## View the results
names(my.data2)
# [1] "landuse"       "units"         "grade"         "clay"         
# [5] "lincoln"       "basinandrange" "mccartney"     "maple"   
于 2012-11-06T19:41:22.030 回答
15

简单的解决方案

names(DF) <- toupper(names(DF))

于 2020-03-30T16:12:54.430 回答
13

现代解决方案

现在这是一项工作janitor::clean_names(),只需选择case适合您需要的参数即可。

于 2018-12-12T05:04:01.367 回答
8

data.table 语法,相信会节省更多时间和效率。它也是一个单行语句,甚至更短。

library(data.table)
setnames(my.data2, tolower(names(my.data2[4:8])))

#   landuse units grade clay lincoln basinandrange mccartney maple
#1:   apple acres   AAA    0       2             3         4     6
#2:   apple acres    AA 1000     900            NA        NA   700
#3:    pear acres    AA   10      20            NA        30    40
#4:   peach acres   AAA  500     400           350       300   200
于 2017-07-05T14:40:43.697 回答
6

一个“整洁”的解决方案:

library(dplyr)

my.data2.mod <- my.data2 %>% 
  rename_at(c("CLAY", "LINCOLN", "BASINANDRANGE", "MCCARTNEY",  "MAPLE"),
            .funs = tolower)

names(my.data2.mod) 
# [1] "landuse"       "units"         "grade"         "clay"         
# [5] "lincoln"       "basinandrange" "mccartney"     "maple"   

此外,要回答原始问题并使某些情况大写,您可以使用该snakecase包:

library(snakecase)

my.data2.mod = my.data2 %>% 
  rename_at(
    c("CLAY", "LINCOLN", "BASINANDRANGE", "MCCARTNEY",  "MAPLE"),
    .funs = list(
      ~ to_upper_camel_case(., 
                            abbreviations = c("McCartney", "BasinandRange")
                            )
      )
    )

names(my.data2.mod)
# [1] "landuse"       "units"         "grade"         "Clay"         
# [5] "Lincoln"       "BasinandRange" "McCartney"     "Maple" 
于 2019-07-25T12:32:06.400 回答
6

结合这里的两个答案,我想出了一个优雅的tidy方法:

这通过大写每个单词的第一个字母来重命名所有列/变量名称。

library(tidyverse)

my.data2 %>%
  rename_with(str_to_title)
于 2021-01-07T11:30:34.143 回答
4

另外一个选项:

colnames(df) <- stringr::str_to_title(colnames(df))
于 2020-05-27T12:37:41.757 回答
2

我使用了 Josh O'Brien 的答案,但最终编写了下面的代码,该代码创建了第一个字母为大写字母和其他字母为小写字母的列名,除了原始帖子中处理的一些例外情况。下面我使用了与原始帖子中相同的数据集,但将该数据读入 R 的方式不同,其中n.col确定了数据文件中的列数:

n.col <- as.numeric(length(scan("c:/users/mark w miller/simple R programs/names_with_capital_letters.txt", 
         what="character", nlines=1)))

my.data2 <- read.table(file = "c:/users/mark w miller/simple R programs/names_with_capital_letters.txt", 
            na.string=NA, header = T, colClasses = c('character', 'character', 'character', 
            rep('numeric', (n.col[1] - 3))))

first.letter  <- substring(names(my.data2)[-1:-3], 1, 1)
other.letters <- tolower(substring(names(my.data2)[-1:-3], 2))
newnames      <- paste(first.letter, other.letters, sep="")

names(my.data2)[-1:-3] <- newnames
names(my.data2)[names(my.data2)=="Basinandrange"]   <- "BasinandRange"
names(my.data2)[names(my.data2)=="Mccartney"]       <- "McCartney"

my.data2

#   landuse units grade Clay Lincoln BasinandRange McCartney Maple
# 1   apple acres   AAA    0       2             3         4     6
# 2   apple acres    AA 1000     900            NA        NA   700
# 3    pear acres    AA   10      20            NA        30    40
# 4   peach acres   AAA  500     400           350       300   200
于 2012-11-11T19:51:47.077 回答
0

这将使每一列都大写。

rename_with(names,toupper)
于 2021-08-26T14:14:08.013 回答