将数据框中所有字符变量中的所有值从小写转换为大写
Posted
技术标签:
【中文标题】将数据框中所有字符变量中的所有值从小写转换为大写【英文标题】:Convert from lowercase to uppercase all values in all character variables in dataframe 【发布时间】:2013-05-07 03:57:12 【问题描述】:我有一个mixed dataframe 的字符和数字变量。
city,hs_cd,sl_no,col_01,col_02,col_03
Austin,1,2,,46,Female
Austin,1,3,,32,Male
Austin,1,4,,27,Male
Austin,1,5,,20,Female
Austin,2,2,,42,Female
Austin,2,1,,52,Male
Austin,2,3,,25,Male
Austin,2,4,,22,Female
Austin,3,3,,30,Female
Austin,3,1,,65,Female
我想将数据框中的所有小写字符转换为大写。有没有办法一次性做到这一点,而无需对每个字符变量重复执行?
【问题讨论】:
【参考方案1】:从以下示例数据开始:
df <- data.frame(v1=letters[1:5],v2=1:5,v3=letters[10:14],stringsAsFactors=FALSE)
v1 v2 v3
1 a 1 j
2 b 2 k
3 c 3 l
4 d 4 m
5 e 5 n
你可以使用:
data.frame(lapply(df, function(v)
if (is.character(v)) return(toupper(v))
else return(v)
))
这给出了:
v1 v2 v3
1 A 1 J
2 B 2 K
3 C 3 L
4 D 4 M
5 E 5 N
【讨论】:
我刚刚发现这也有效:df = as.data.frame(sapply(df, toupper))【参考方案2】:从dplyr
包中,您还可以将mutate_all()
函数与toupper()
结合使用。这将影响字符和因子类。
library(dplyr)
df <- mutate_all(df, funs=toupper)
【讨论】:
对于从今天开始查看此内容的任何人,请注意mutate_each()
已贬值;相反(假设您希望将整个 data.frame
转换为上/下),请使用 mutate_all()
。
'mutate_at()' 只能用于一个变量
这对我有用:df
确保使用mutate_all(df, .funs = toupper)
以获得正确的语法,否则您将收到错误消息。应该有一个“。”在funs
参数之前。此外,如果您想坚持使用tidyverse
,可以使用stringr
str_to_upper
而不是base
toupper
。【参考方案3】:
对于那些使用任何这些答案的人来说,这里是一个侧面评论。 Juba 的答案很棒,因为如果您的变量是数字或字符串,它非常有选择性。但是,如果您有组合(例如 a1、b1、a2、b2)等。它将无法正确转换字符。
正如@Trenton Hoffman 所说,
library(dplyr)
df <- mutate_each(df, funs(toupper))
同时影响字符和因子类,适用于“混合变量”;例如如果您的变量同时包含字符和数字值(例如 a1),则两者都将转换为因子。总的来说,这不是一个太大的问题,但如果你最终想要匹配 data.frames,例如
df3 <- df1[df1$v1 %in% df2$v1,]
其中 df1 已被转换并且 df2 包含未转换的 data.frame 或类似的,这可能会导致一些问题。解决方法是您必须短暂运行
df2 <- df2 %>% mutate_each(funs(toupper), v1)
#or
df2 <- df2 %>% mutate_each(df2, funs(toupper))
#and then
df3 <- df1[df1$v1 %in% df2$v1,]
如果您使用基因组数据,那么知道这会派上用场。
【讨论】:
mutate_each 已被弃用 - 最新版本 R 的建议是使用 cross()【参考方案4】:如果您需要处理包含您可以使用的因素的 data.frames:
df = data.frame(v1=letters[1:5],v2=1:5,v3=letters[10:14],v4=as.factor(letters[1:5]),v5=runif(5),stringsAsFactors=FALSE)
df
v1 v2 v3 v4 v5
1 a 1 j a 0.1774909
2 b 2 k b 0.4405019
3 c 3 l c 0.7042878
4 d 4 m d 0.8829965
5 e 5 n e 0.9702505
sapply(df,class)
v1 v2 v3 v4 v5
"character" "integer" "character" "factor" "numeric"
使用 mutate_each_ 将因子转换为字符,然后将所有转换为大写
upper_it = function(X)X %>% mutate_each_( funs(as.character(.)), names( .[sapply(., is.factor)] )) %>%
mutate_each_( funs(toupper), names( .[sapply(., is.character)] )) # convert factor to character then uppercase
给
upper_it(df)
v1 v2 v3 v4
1 A 1 J A
2 B 2 K B
3 C 3 L C
4 D 4 M D
5 E 5 N E
虽然
sapply( upper_it(df),class)
v1 v2 v3 v4 v5
"character" "integer" "character" "character" "numeric"
【讨论】:
【参考方案5】:在R中使用apply函数很简单
f <- apply(f,2,toupper)
无需检查列是字符还是其他类型。
【讨论】:
请注意,这会将数字列转换为字符,还将数据从 data.frame 转换为矩阵。【参考方案6】:另一种选择是结合使用 mutate_if()
和 str_to_upper()
函数,两者都来自 tidyverse 包:
df %>% mutate_if(is.character, str_to_upper) -> df
这会将数据框中的所有字符串变量转换为大写。
str_to_lower()
则相反。
【讨论】:
【参考方案7】:或者,如果您只想将特定行转换为大写,请使用以下代码:
df[[1]] <- toupper(df[[1]])
【讨论】:
【参考方案8】:dplyr >= 1.0.0
以_if
、_at
、_all
结尾的作用域动词已被packageVersion("dplyr")
1.0.0 或更高版本中的across()
的使用所取代。要做到这一点,请使用across
:
df %>%
mutate(across(where(is.character), toupper))
across
的第一个参数是使用tidyselect 语法转换哪些列。以上将在所有字符列中应用该函数。
across
的第二个参数是要应用的函数。这还支持 lambda 样式语法:~ toupper(.x)
,这使得设置附加函数参数变得简单明了。
数据
df <- structure(list(city = c("Austin", "Austin", "Austin", "Austin",
"Austin", "Austin", "Austin", "Austin", "Austin", "Austin"),
hs_cd = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L), sl_no = c(2L,
3L, 4L, 5L, 2L, 1L, 3L, 4L, 3L, 1L), col_01 = c(NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA), col_02 = c(46L, 32L, 27L, 20L,
42L, 52L, 25L, 22L, 30L, 65L), col_03 = c("Female", "Male",
"Male", "Female", "Female", "Male", "Male", "Female", "Female",
"Female")), class = "data.frame", row.names = c(NA, -10L))
【讨论】:
以上是关于将数据框中所有字符变量中的所有值从小写转换为大写的主要内容,如果未能解决你的问题,请参考以下文章