gpt4 book ai didi

regex - R中data.table中一列的子字符串字符

转载 作者:行者123 更新时间:2023-12-04 22:44:07 27 4
gpt4 key购买 nike

是否有更“r”的方式从 data.table 中的列的较长字符串中分出两个有意义的字符?

我有一个 data.table,其中有一列带有“学位字符串”......某人获得的学位和毕业年份的速记代码。

> srcDT<- data.table(
alum=c("Paul Lennon","Stevadora Nicks","Fred Murcury"),
degree=c("W72","WG95","W88")
)

> srcDT
alum degree
1: Paul Lennon W72
2: Stevadora Nicks WG95
3: Fred Murcury W88

我需要从学位中提取年份的数字,并将其放入名为“degree_year”的新列中

没问题:
> srcDT[,degree_year:=substr(degree,nchar(degree)-1,nchar(degree))]

> srcDT
alum degree degree_year
1: Paul Lennon W72 72
2: Stevadora Nicks WG95 95
3: Fred Murcury W88 88

如果它总是那么简单就好了。
问题是,度数字符串只是有时看起来像上面那样。更多的时候,它们看起来像这样:
srcDT<- data.table(
alum=c("Ringo Harrison","Brian Wilson","Mike Jackson"),
degree=c("W72 C73","WG95 L95","W88 WG90")
)

我只对我关心的角色旁边的2个数字感兴趣:W&WG(如果W和WG都在,我只关心WG)

这是我解决它的方法:
x <-srcDT$degree                     ##grab just the degree column
z <-character() ## create an empty character vector
degree.grep.pattern <-c("WG[0-9][0-9]","W[0-9][0-9]")
## define a vector of regex's, in the order
## I want them

for(i in 1:length(x)){ ## loop thru all elements in degree column
matched=F ## at the start of the loop, reset flag to F
for(j in 1:length(degree.grep.pattern)){
## loop thru all elements of the pattern vector

if(length(grep(degree.grep.pattern[j],x[i]))>0){
## see if you get a match

m <- regexpr(degree.grep.pattern[j],x[i])
## if you do, great! grab the index of the match
y<-regmatches(x[i],m) ## then subset down. y will equal "WG95"
matched=T ## set the flag to T
break ## stop looping
}
## if no match, go on to next element in pattern vector
}

if(matched){ ## after finishing the loop, check if you got a match
yr <- substr(y,nchar(y)-1,nchar(y))
## if yes, then grab the last 2 characters of it
}else{
#if you run thru the whole list and don't match any pattern at all, just
# take the last two characters from the affilitation
yr <- substr(x[i],nchar(as.character(x[i]))-1,nchar(as.character(x[i])))
}
z<-c(z,yr) ## add this result (95) to the character vector
}
srcDT$degree_year<-z ## set the column to the results.

> srcDT
alum degree degree_year
1: Ringo Harrison W72 C73 72
2: Brian Wilson WG95 L95 95
3: Mike Jackson W88 WG90 90

这有效。 100% 的时间。没有错误,没有错配。
问题是:它不能扩展。给定一个包含 10k 行或 100k 行的数据表,它确实变慢了。

有没有更聪明、更好的方法来做到这一点?这个解决方案对我来说非常“C”。不是很“R”。

关于改进的想法?

注意:我举了一个简化的例子。在实际数据中,大约有 30 种不同的学位可能组合,结合不同的年份,大约有 540 种独特的学位字符串组合。
另外,我给 degree.grep.pattern 只匹配了 2 个模式。在我正在做的实际工作中,有 7 或 8 个模式可以匹配。

最佳答案

看起来(根据 OP)评论,不存在 "WG W" 的情况,那么一个简单的正则表达式解决方案应该可以完成这项工作

srcDT[ , degree_year := gsub(".*WG?(\\d+).*", "\\1", degree)]
srcDT
# alum degree degree_year
# 1: Ringo Harrison W72 C73 72
# 2: Brian Wilson WG95 L95 95
# 3: Mike Jackson W88 WG90 90

关于regex - R中data.table中一列的子字符串字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35004781/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com