我希望找到字符串的第一个和最后一个非点元素的位置。理想情况下,我希望在基座regex
中使用R
执行此操作。我已经编写了R
代码来解决问题。但是,我对regex
解决方案感兴趣。感谢您的任何建议。
以下是获取所需结果的示例数据集和R
代码。此代码拆分字符串并使用which
来定位每个非点的位置。然后,我使用min
和max
逐行获取aggregate
和merge
列。但是,我怀疑regex
会更高效,更有趣。
my.data <- read.table(text = '
my.string state cov
11....... A 1
111...... A 2
.1.1..... B 3
....1.... B 4
..1.11... C 5
...1..... C 6
......... D 7
.....1.1. D 8
', header = TRUE, stringsAsFactors = FALSE)
new.data <- data.frame(do.call(rbind, strsplit(my.data$my.string,'')), my.data[,2:3], stringsAsFactors = FALSE)
new.data2 <- new.data[,1:9]
new.data2[new.data2 == '.'] <- NA
new.data2 <- t(apply(new.data2, 1, as.numeric))
not.NA <- as.data.frame(which(!is.na(new.data2), arr.ind = TRUE))
my.min.max3 <- with(not.NA, aggregate(not.NA$col, by = list(not.NA$row), FUN = function(x) c(MIN = min(x), MAX = max(x)) ))
my.min.max3 <- do.call(data.frame, my.min.max3)
colnames(my.min.max3) <- c('my.row', 'min', 'max')
my.min.max3
my.row <- 1:nrow(my.data)
my.output <- merge(my.row, my.min.max3, by.x=0, by.y = 'my.row', all=TRUE)
my.output <- my.output[,-1]
colnames(my.output) <- c('my.row', 'min', 'max')
my.output
#
# my.row min max
# 1 1 1 2
# 2 2 1 3
# 3 3 2 4
# 4 4 5 5
# 5 5 3 6
# 6 6 4 4
# 7 7 NA NA
# 8 8 6 8
#
答案 0 :(得分:4)
你可以这样做,
> data.frame(my.data[,1], do.call(rbind, gregexpr("^\\.*\\K[^.]|[^.](?=\\.*$)", my.data[,1], perl=T)))
my.data...1. X1 X2
1 11....... 1 2
2 111...... 1 3
3 .1.1..... 2 4
4 ....1.... 5 5
5 ..1.11... 3 6
6 ...1..... 4 4
7 ......... -1 -1
8 .....1.1. 6 8
答案 1 :(得分:2)
您可以尝试:
minmax <- t(sapply(my.data[,1], function(x) {
y <- gregexpr("[^.]", x)[[1]]
return(c(min=min(y), max=max(y)))}))
minmax[minmax==-1] <- NA
my.output <- data.frame(my.row=1:nrow(my.data), minmax)
#> my.output
# my.row min max
#11....... 1 1 2
#111...... 2 1 3
#.1.1..... 3 2 4
#....1.... 4 5 5
#..1.11... 5 3 6
#...1..... 6 4 4
#......... 7 NA NA
#.....1.1. 8 6 8
答案 2 :(得分:2)
我会使用stringi
包
library(stringi)
cbind(my.data[1], with(my.data,
cbind(min = stri_locate_first_fixed(my.string, "1")[, 1],
max = stri_locate_last_fixed(my.string, "1")[, 2])))
# my.string min max
# 1 11....... 1 2
# 2 111...... 1 3
# 3 .1.1..... 2 4
# 4 ....1.... 5 5
# 5 ..1.11... 3 6
# 6 ...1..... 4 4
# 7 ......... NA NA
# 8 .....1.1. 6 8