【发布时间】:2016-05-20 01:52:53
【问题描述】:
我希望将字符串拆分为不重叠的段,其中段的端点是点域内的数字。我可以使用下面的代码来做到这一点。但是,这段代码似乎过于复杂,并且涉及到嵌套的for-loops。有没有更简单的方法,最好在基础R 中使用regex?
这是一个示例和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家庭功能。如果有人没有发布更好的答案,明天再看看。 -
也许,根据您的目标,将
my.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)))或其他非字符对象可能更方便?