Regex 抓取具有特殊字符和大写字母的列
我有一个数据框,我试图在数据框中循环,以识别那些包含特殊字符或都是大写字母的列 我尝试了一些方法,但没有尝试在循环中捕捉列名Regex 抓取具有特殊字符和大写字母的列,regex,r,Regex,R,我有一个数据框,我试图在数据框中循环,以识别那些包含特殊字符或都是大写字母的列 我尝试了一些方法,但没有尝试在循环中捕捉列名 data = data.frame(one=c(1,3,5,1,3,5,1,3,5,1,3,5), two=c(1,3,5,1,3,5,1,3,5,1,3,5), thr=c("A","B","D","E","F","G","H","I","J","H","I","J"), fou=c("A","B","D
data = data.frame(one=c(1,3,5,1,3,5,1,3,5,1,3,5), two=c(1,3,5,1,3,5,1,3,5,1,3,5),
thr=c("A","B","D","E","F","G","H","I","J","H","I","J"),
fou=c("A","B","D","A","B","D","A","B","D","A","B","D"),
fiv=c(1,3,5,1,3,5,1,3,5,1,3,5),
six=c("A","B","D","E","F","G","H","I","J","H","I","J"),
sev=c("A","B","D","A","B","D","A","B","D","A","B","D"),
eig=c("A","B","D","A","B","D","A","B","D","A","B","D"),
nin=c(1.24,3.52,5.33,1.44,3.11,5.33,1.55,3.66,5.33,1.32,3.54,5.77),
ten=c(1:12),
ele=rep(1,12),
twe=c(1,2,1,2,1,2,1,2,1,2,1,2),
thir=c("THiS","THAT34","T(&*(", "!!!","@$#","$Q%J","who","THIS","this","this","this","this"),
stringsAsFactors = FALSE)
data
colls <- c()
spec=c("$","%","&")
for( col in names(data) ) {
if( length(strings[stringr::str_detect(data[,col], spec)]) >= 1 ){
print("HORRAY")
colls <- c(collls, col)
}
else print ("NOOOOOOOOOO")
}
for( col in names(data) ) {
if( any(data[,col]) %in% spec ){
print("HORRAY")
colls <- c(collls, col)
}
else print ("NOOOOOOOOOO")
}
data=data.frame(一=c(1,3,5,1,3,5,1,3,5,1,3,5),二=c(1,3,5,1,3,5,1,3,5),
thr=c(“A”、“B”、“D”、“E”、“F”、“G”、“H”、“I”、“J”、“H”、“I”、“J”),
fou=c(“A”、“B”、“D”、“A”、“B”、“D”、“A”、“B”、“D”、“A”、“B”、“D”、“A”、“B”、“D”),
fiv=c(1,3,5,1,3,5,1,3,5,1,3,5),
六=c(“A”、“B”、“D”、“E”、“F”、“G”、“H”、“I”、“J”、“H”、“I”、“J”),
sev=c(“A”、“B”、“D”、“A”、“B”、“D”、“A”、“B”、“D”、“A”、“B”、“D”、“A”、“B”、“D”),
eig=c(“A”、“B”、“D”、“A”、“B”、“D”、“A”、“B”、“D”、“A”、“B”、“D”、“A”、“B”、“D”),
nin=c(1.24,3.52,5.33,1.44,3.11,5.33,1.55,3.66,5.33,1.32,3.54,5.77),
十=c(1:12),
ele=rep(1,12),
twe=c(1,2,1,2,1,2,1,2,1,2,1,2),
thir=c(“这个”、“那个34”、“T(&*(“,”!!!”、“@$#”、“Q%J”、“谁”、“这个”、“这个”、“这个”、“这个”),
stringsAsFactors=FALSE)
数据
colls=1){
打印(“HORRAY”)
colls我会将数据折叠成字符串(每行一个字符串)
您还可以使用上的来获取原始数据帧的相应行号,该包含_spec
或仅包含_caps
。我认为使用字符串而不是按行数据帧元素会快得多-只要您想搜索整个字符串,而不是特定条件下的特定列离子。我将使用grep()搜索您感兴趣的图案。请参阅
[:大写:
匹配任何大写字母
将其与锚(^,$)组合并匹配一次或多次(+)将给出^[[:upper:]+$
,并且只应完全匹配大写字母的条目
以下内容将匹配玩具数据集中的特殊字符(但不能保证匹配真实数据集中的所有特殊字符,即表单提要、回车)
[:punct:
#匹配标点符号-!“$%&'()*+,-./:;<=>?@[\]^{{124;}~
请注意,您可以手动定义特殊字符,而不是使用[:punct://code>
我们可以在数据集的第一行尝试生成的代码:
#Using grepl() rather than grep() so that we return a list of logical values.
grepl(x= data[1,], pattern = "^[[:upper:]]+$|[[:punct:]]")
[1] FALSE FALSE TRUE TRUE FALSE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE
除了第九列的值为1.24外,这给了我们预期的响应。此处小数点被识别为标点符号,并被标记为匹配。
我们可以添加一个“负前瞻断言”
(?!\\)
,在测试句点是否为标点字符之前,将其从考虑范围中删除。注意,我们使用\来转义句点
grepl(x= data[1,], perl = TRUE, pattern = "(?!\\.)(^[[:upper:]]+$|[[:punct:]])")
[1] FALSE FALSE TRUE TRUE FALSE TRUE TRUE TRUE FALSE FALSE FALSE FALSE TRUE
这将返回更好的响应-它现在不再匹配小数位。注意:这可能不是您想要的,因为此模式也不会匹配字符字段中的任何句号。您需要进一步优化模式
我不想使用“for循环”在数据帧的每一行上重复这段代码,而是使用“更像R”的矢量化
为此,我们必须将脚本转换为一个函数,我们将使用apply()调用该函数
在示例数据集中,所有行都有一个包含特殊字符或全大写字母字符串的条目。这并不奇怪,因为示例数据集中的许多列都是单大写字母列表
如果您只对第十三列中的哪些值符合所述标准感兴趣,您可以使用:
matches <- grepl(x= data$thir, perl = TRUE, pattern = "(?!\\.)(^[[:upper:]]+$|[[:punct:]])")
matches
[1] FALSE FALSE TRUE TRUE TRUE TRUE FALSE TRUE FALSE FALSE FALSE FALSE
要在不匹配的行上子集数据帧,请执行以下操作:
data[matches,]
one two thr fou fiv six sev eig nin ten ele twe thir
3 5 5 D D 5 D D D 5.33 3 1 1 T(&*(
4 1 1 E A 1 E A A 1.44 4 1 2 !!!
5 3 3 F B 3 F B B 3.11 5 1 1 @$#
6 5 5 G D 5 G D D 5.33 6 1 2 $Q%J
8 3 3 I B 3 I B B 3.66 8 1 2 THIS
data[!matches,]
one two thr fou fiv six sev eig nin ten ele twe thir
1 1 1 A A 1 A A A 1.24 1 1 1 THiS
2 3 3 B B 3 B B B 3.52 2 1 2 THAT34
7 1 1 H A 1 H A A 1.55 7 1 1 who
9 5 5 J D 5 J D D 5.33 9 1 1 this
10 1 1 H A 1 H A A 1.32 10 1 2 this
11 3 3 I B 3 I B B 3.54 11 1 1 this
12 5 5 J D 5 J D D 5.77 12 1 2 this
请注意,使用的正则表达式与34不匹配,因为它不是完全由大写字母组成的,在末尾有数字34
编辑:
要获取列名列表,以识别满足编辑条件的列,请使用上文所述的myFunction
:
colnames(data)[apply(X = data, 2, myFunction)]
"thr" "fou" "six" "sev" "eig" "thir"
apply()中的数字从1变为2,以跨列而不是跨行重复。我们将逻辑匹配列表apply()的输出(TRUE或FALSE)传递给colnames(data)-这将通过子集返回匹配的列名。将数据放在列中而不仅仅作为字符串(每行一个字符串)有何意义?这就是数据的方式,我还必须循环遍历逻辑、数字等列。我想我可以提取它们并将其保存为向量,但在一天结束时,目标是获取包含特殊字符的变量的列名,因此,如果您包含在你的问题中,我已经修改了我下面的答案,以检查每一列,然后返回匹配列名称的列表。
data[matches,]
one two thr fou fiv six sev eig nin ten ele twe thir
3 5 5 D D 5 D D D 5.33 3 1 1 T(&*(
4 1 1 E A 1 E A A 1.44 4 1 2 !!!
5 3 3 F B 3 F B B 3.11 5 1 1 @$#
6 5 5 G D 5 G D D 5.33 6 1 2 $Q%J
8 3 3 I B 3 I B B 3.66 8 1 2 THIS
data[!matches,]
one two thr fou fiv six sev eig nin ten ele twe thir
1 1 1 A A 1 A A A 1.24 1 1 1 THiS
2 3 3 B B 3 B B B 3.52 2 1 2 THAT34
7 1 1 H A 1 H A A 1.55 7 1 1 who
9 5 5 J D 5 J D D 5.33 9 1 1 this
10 1 1 H A 1 H A A 1.32 10 1 2 this
11 3 3 I B 3 I B B 3.54 11 1 1 this
12 5 5 J D 5 J D D 5.77 12 1 2 this
colnames(data)[apply(X = data, 2, myFunction)]
"thr" "fou" "six" "sev" "eig" "thir"