将部分字符串转换为大写(或小写)

Convert part of string to upper (or lower) case

我有一个带有样本位置的矢量,这是一个样本:

test <- c("Aa, Heeswijk T1", "Aa, Heeswijk t1", 
          "Aa, Middelrode t2", "Aa, Middelrode p1",
          "Aa, Heeswijk t1a", "Aa, Heeswijk t3b",
          "Aa, test1 T1", "Aa, test2 t1")

这些字符串由位置名称 ("Aa, Heeswijk")、路线代码 ("T1"、"p2"、"t3") 和子路线 ("a" 或 "b")。不幸的是,路线代码(t1、t2、p1、t1a)有时是大写的,有时是小写的。 我希望所有路由代码都大写,名称和子路由保持不变。我的预期结果是:

"Aa, Heeswijk T1", "Aa, Heeswijk T1", 
"Aa, Middelrode T2", "Meander Assendelft P1",
"Aa, Heeswijk T1a", "Aa, Heeswijk T3b"
"Aa, test1 T1", "Aa, test2 T1"

我查看了 toupper() 但是整个字符串都变了。我也可以使用 gsub:

gsub("t1","T1", test)
gsub("t2","T2", test)
#etc.

但一定有更好的 R 式方法?!
注意:路由代码始终为 2 个字符长,包含一个字符和一个整数,并以 space 开头。因此要更改为 upper 的字符始终位于倒数第二个或第三个。

我们可以使用正则表达式环视。我们匹配并捕获一个以小写字母开头的单词,后跟正则表达式先行编号 ((?=[0-9])) 作为一个组(使用括号),在替换中我们使用 \U 后跟捕获组将其转换为大写.

 sub('\b([a-z])(?=[0-9])', '\U\1', test, perl=TRUE)
 #[1] "Aa, Heeswijk T1"       "Aa, Heeswijk T1"       "Aa, Middelrode T2"    
 #[4] "Meander Assendelft P1" "Aa, Heeswijk T1a"      "Aa, Heeswijk T3b"    

或者不使用环视,我们可以用两个捕获组来做到这一点。

 sub('\b([a-z])([0-9])', '\U\1\2', test, perl=TRUE)

更新

使用来自 OP post

的更新 'test' 进行测试
sub('\b([a-z])(?=[0-9])', '\U\1', test, perl=TRUE)
#[1] "Aa, Heeswijk T1"   "Aa, Heeswijk T1"   "Aa, Middelrode T2"
#[4] "Aa, Middelrode P1" "Aa, Heeswijk T1a"  "Aa, Heeswijk T3b" 
#[7] "Aa, test1 T1"      "Aa, test2 T1"     

如果您想避免正则表达式(我不建议这样做),您可以练习一些 R 体操:

df <- data.frame(do.call(rbind, strsplit(test, " ")), stringsAsFactors=FALSE)

现在您将所有内容拆分为数据框的列:

> df
   X1         X2  X3
1 Aa,   Heeswijk  T1
2 Aa,   Heeswijk  t1
3 Aa, Middelrode  t2
4 Aa, Middelrode  p1
5 Aa,   Heeswijk t1a
6 Aa,   Heeswijk t3b
7 Aa,      test1  T1
8 Aa,      test2  t1

下一个:

df[, 3]  <- paste(toupper(substr(df[, 3], 1, 2)), substr(df[, 3], 3, nchar(df[, 3])), sep="")

将进行大写:

> df
   X1         X2  X3
1 Aa,   Heeswijk  T1
2 Aa,   Heeswijk  T1
3 Aa, Middelrode  T2
4 Aa, Middelrode  P1
5 Aa,   Heeswijk T1a
6 Aa,   Heeswijk T3b
7 Aa,      test1  T1
8 Aa,      test2  T1

最后,把它全部折叠起来:

ans <- apply(df, 1, paste, collapse=" ")
ans

...这给你:

> ans
[1] "Aa, Heeswijk T1"   "Aa, Heeswijk T1"   "Aa, Middelrode T2" "Aa, Middelrode P1" "Aa, Heeswijk T1a"  "Aa, Heeswijk T3b"  "Aa, test1 T1"     
[8] "Aa, test2 T1"