将部分字符串转换为大写(或小写)
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"
我有一个带有样本位置的矢量,这是一个样本:
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"