我正在尝试将列中的第一个字符串转换为小写字母。 我试过了:
diamonds %>% map(cut,~substr(.x,1,1)<-tolower(substr(.x,1,1)))
diamonds %>% mutate(cut= map(cut,~substr(.x,1,1)<-tolower(substr(.x,1,1))))
两者都给了我错误信息。我无法弄清楚为什么...... 顺便说一下,stringr中是否有任何函数可以将字符串的第一个字母大写?喜欢str_capitalize? 感谢是否有人可以提供帮助。感谢。
答案 0 :(得分:2)
下载到C ++,它非常简单+快速:
lc_first <- inline::rcpp(signature(x="std::vector < std::string >"), '
std::vector < std::string > s = as< std::vector < std::string > >(x);
unsigned int input_size = s.size();
for (unsigned int i=0; i<input_size; i++) s[i][0] = tolower(s[i][0]);
return(wrap(s));
', includes = c("#include <string>", "#include <cctype>"))
lc_first(c("Apple", "Banana", "", "Strawberry"))
## [1] "apple" "banana" "" "strawberry"
您需要先在diamonds
中处理该因素:
library(ggplot2)
library(dplyr)
lc_first <- inline::rcpp(signature(x="std::vector < std::string >"), '
std::vector < std::string > s = as< std::vector < std::string > >(x);
unsigned int input_size = s.size();
for (unsigned int i=0; i<input_size; i++) s[i][0] = tolower(s[i][0]);
return(wrap(s));
', includes = c("#include <string>", "#include <cctype>"))
mutate(diamonds, cut = lc_first(as.character(cut)))
## # A tibble: 53,940 x 10
## carat cut color clarity depth table price x y z
## <dbl> <chr> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl>
## 1 0.23 ideal E SI2 61.5 55 326 3.95 3.98 2.43
## 2 0.21 premium E SI1 59.8 61 326 3.89 3.84 2.31
## 3 0.23 good E VS1 56.9 65 327 4.05 4.07 2.31
## 4 0.29 premium I VS2 62.4 58 334 4.20 4.23 2.63
## 5 0.31 good J SI2 63.3 58 335 4.34 4.35 2.75
## 6 0.24 very Good J VVS2 62.8 57 336 3.94 3.96 2.48
## 7 0.24 very Good I VVS1 62.3 57 336 3.95 3.98 2.47
## 8 0.26 very Good H SI1 61.9 55 337 4.07 4.11 2.53
## 9 0.22 fair E VS2 65.1 61 337 3.87 3.78 2.49
## 10 0.23 very Good H VS1 59.4 61 338 4.00 4.05 2.39
## # ... with 53,930 more rows
BUT
如果您有很多字符串,我只会这样做:
microbenchmark::microbenchmark(
rcpp = mutate(diamonds, cut = lc_first(as.character(cut))),
bsub = mutate(diamonds, cut = sub('^(.)', '\\L\\1', cut, perl=TRUE)),
times = 1000
) -> mb
mb
## Unit: milliseconds
## expr min lq mean median uq max neval
## rcpp 5.148179 5.69955 6.597025 6.021698 6.563165 88.57958 1000
## bsub 13.776041 15.25682 16.311123 15.720502 16.701296 88.14688 1000
如果您没有处理大量字符串,IMO 10ms不值得Rcpp依赖。
我怀疑大写版本并不难辨别。
在云雀上我试过了:
diamonds$cut <- as.character(diamonds$cut)
microbenchmark::microbenchmark(
rcpp = mutate(diamonds, cut = lc_first(cut)),
bsub = mutate(diamonds, cut = sub('^(.)', '\\L\\1', cut, perl=TRUE)),
subs = {
substr(diamonds$cut, 1, 1) <- tolower(substr(diamonds$cut, 1, 1))
diamonds
},
times=200
) -> mb
mb
## Unit: milliseconds
## expr min lq mean median uq max neval
## rcpp 4.746636 5.157223 5.625221 5.439006 5.801081 10.10990 200
## bsub 13.154218 13.764529 14.721534 14.251513 15.043204 22.48961 200
## subs 16.552250 17.377025 19.665733 18.146310 20.256965 90.61097 200
(需要提前将因子标准化为字符向量)
我猜测subset() <-
本来会更快,但显然不是。
答案 1 :(得分:1)
您可以使用\\L
将捕获的组转换为正则表达式中的小写,这样您就可以使用sub
捕获第一个字母,并将其替换为\\L\\1
,其中\\1
1}}代表捕获的字母,\\L
将其转换为小写:
head(diamonds)
# A tibble: 6 x 10
# carat cut color clarity depth table price x y z
# <dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl>
#1 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43
#2 0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31
#3 0.23 Good E VS1 56.9 65 327 4.05 4.07 2.31
#4 0.29 Premium I VS2 62.4 58 334 4.20 4.23 2.63
#5 0.31 Good J SI2 63.3 58 335 4.34 4.35 2.75
#6 0.24 Very Good J VVS2 62.8 57 336 3.94 3.96 2.48
diamonds %>% mutate(cut = sub('^(.)', '\\L\\1', cut, perl=T)) %>% head
# A tibble: 6 x 10
# carat cut color clarity depth table price x y z
# <dbl> <chr> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl>
#1 0.23 ideal E SI2 61.5 55 326 3.95 3.98 2.43
#2 0.21 premium E SI1 59.8 61 326 3.89 3.84 2.31
#3 0.23 good E VS1 56.9 65 327 4.05 4.07 2.31
#4 0.29 premium I VS2 62.4 58 334 4.20 4.23 2.63
#5 0.31 good J SI2 63.3 58 335 4.34 4.35 2.75
#6 0.24 very Good J VVS2 62.8 57 336 3.94 3.96 2.48
对于第二个问题,您可能需要str_to_title
吗?
stringr::str_to_title("hello world")
# [1] "Hello World"
答案 2 :(得分:1)
如果您想要将字符串的第一个字母大写,str_to_title()
就是您正在寻找的内容。
对于您的其他问题,转换为小写,您可以使用正则表达式和sub
。
> text = 'LonG5 story ShoRt'
> sub("(\\w)(\\w*)", "\\L\\1\\E\\2", text, perl=TRUE)
[1] "lonG5 story ShoRt"
这个正则表达式将找到任何单词字符,并将第一个发生(这是我假设的第一个字符)转换为小写,而其余的匹配保持不变。
应用于您的示例:
untitle = function(text) {
sub("(\\w)(\\w*)", "\\L\\1\\E\\2", text, perl=TRUE)
}
diamonds %>% mutate(cut = untitle(cut))
答案 3 :(得分:0)
如果整个数据都是字符串,那么下面的代码应该有效:
d=as.data.frame(diamonds[,2:4])
data=sapply(d,as.character)
sapply(data,function(x)`substring<-`(x,1,1,tolower(x)))
我不知道您是想要更改所有列还是特定列。我不知道你的对象是否有不同类的组合。希望这会有所帮助。
您是否需要更改列名称或列中的元素?