我希望将字符串分割成不重叠的片段,其中片段的端点是点字段内的数字。我可以使用下面的代码来实现。然而,这段代码似乎过于复杂,并涉及嵌套的for循环。有没有更简单的方法,最好是在基本的R中使用正则表达式?
以下是示例和期望的结果
以下是示例和期望的结果
desired.result
。my.data <- read.table(text = '
my.string cov1 cov2
11....... 1 A
1.1.2.1.1 2 B
1234..... 3 C
1...2...3 4 C
..3..4... 5 D
', header = TRUE, stringsAsFactors = FALSE)
desired.result <- read.table(text = '
my.string cov1 cov2
11....... 1 A
1.1...... 2 B
..1.2.... 2 B
....2.1.. 2 B
......1.1 2 B
12....... 3 C
.23...... 3 C
..34..... 3 C
1...2.... 4 C
....2...3 4 C
..3..4... 5 D
', header = TRUE, stringsAsFactors = FALSE, na.strings = 'NA')
new.data <- data.frame(do.call(rbind, strsplit(my.data$my.string,'')), stringsAsFactors = FALSE)
n.segments <- rowSums(!(new.data[1:ncol(new.data)] == '.')) - 1
my.end.points <- do.call(rbind, gregexpr("[0-9]", my.data$my.string, perl=TRUE))
my.end.point.char <- do.call(rbind, strsplit(my.data$my.string, ""))
my.end.point.char <- t(apply(my.end.point.char, 1, as.numeric))
new.strings <- matrix('.', nrow = sum(n.segments), ncol = max(nchar(my.data$my.string)))
new.cov <- as.data.frame(matrix(NA, nrow = sum(n.segments), ncol = (ncol(my.data) - 1)))
m <- 1
for(i in 1:nrow(new.data)) {
for(j in 1:n.segments[i]) {
for(k in 1:ncol(new.strings)) {
new.strings[m, my.end.points[i, j ] ] <- my.end.point.char[i, my.end.points[i, j ]]
new.strings[m, my.end.points[i, (j+1)] ] <- my.end.point.char[i, my.end.points[i,(j+1)]]
new.cov[m,] <- my.data[i, c(2:ncol(my.data))]
}
m <- m + 1
}
}
my.result <- data.frame(my.string = apply(new.strings, 1, function(x) paste0(x, collapse = '')), stringsAsFactors = FALSE)
my.result <- data.frame(my.result, new.cov)
colnames(my.result) <- names(my.data)
all.equal(desired.result, my.result)
# [1] TRUE
s <- '1.1.2.1.1'; s <- unlist(strsplit(s, '*')); t(apply(combn(which(s != '.'), 2), 2, function(x) {y <- rep('.', 9); y[x] <- s[x]; y}));
仍需要更多的apply
家族函数。如果没有人发布更好的答案,明天会再看一下。 - Gopalamy.data$mystring
作为类似于with(list(gr = gregexpr("[[:digit:]]", my.data$my.string)), Map(function(n, i, x) replace(integer(n), i, as.numeric(x)), nchar(my.data$my.string), gr, regmatches(my.data$my.string, gr)))
或其他非字符对象更方便? - alexis_laz