我有大量的数据集,每个数据集都包含很长的列名列表。在某些文件中,列名称都是大写字母,在某些文件中,只有列名的第一个字母大写。我需要附加数据集,并认为在数据集中匹配列名的最简单方法是将全资本名称转换为只有首字母大写的名称。
我希望找到一个通用的解决方案,甚至可能是一个单行。
这是我的示例数据集。所需的名称包含在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
请注意,我添加了名称McCartney
和BasinandRange
,以使事情变得更加现实和困难。但是,如果我能找到一个单行代码来处理95%的名称,并使用上述names
语句来处理McCartney
和BasinandRange
这样的并发症。 / p>
我搜索了互联网,包括StackOverflow档案,却没有找到解决方案。对不起,如果我忽略了一个。谢谢你的帮助。
答案 0 :(得分:27)
这是一个实现“数据集中匹配列名的最简单方法”的单线程,我能想到:
## 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"
答案 1 :(得分:6)
简易解决方案
names(DF) <- toupper(names(DF))
答案 2 :(得分:3)
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
答案 3 :(得分:2)
另一个选择:
colnames(df) <- stringr::str_to_title(colnames(df))
答案 4 :(得分:2)
结合这里的两个答案,我想出了一个优雅的 tidy
方法:
这通过将每个单词的第一个字母大写来重命名所有列/变量名称。
library(tidyverse)
my.data2 %>%
rename_with(str_to_title)
答案 5 :(得分:1)
我使用了Josh O'Brien的答案,但最终编写了下面的代码,用第一个字母创建列名
大写字母和小写字母的其他字母,除了原始帖子中处理的一些例外情况。下面我使用了与原始帖子相同的数据集,但是以n.col
确定数据文件中列数的方式将数据读入R中的方式不同:
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
答案 6 :(得分:0)
这是janitor::clean_names()
的工作,只需选择适合您需要的case
参数即可。
答案 7 :(得分:0)
“整洁”的解决方案:
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"