多次提取表达式后的数字

时间:2017-07-31 19:49:39

标签: r regex multiple-columns

我想在表达式“BINDING”之后立即提取数字,并在每次看到该表达式时将其放入新列中。

例: 转动此列

Binding site
BINDING 346 346 jakdjf;aj [0984]. BINDING 28 28 jdalkjda.
BINDING 12 12 jklbasdjf;la.

到此

Bindsite1   Bindsite2                                              
346         28
12          NA

我可以用

提取第一个数字
fulldata <- fulldata %>% 
   extract(`Binding site`, into=c("bind"),
      regex = "(?<=BINDING\\s)([0-9]+)", 
      remove = FALSE)

但我不确定你是否可以使用此功能进行多次提取。注意:我不知道我需要多少列,但我认为它大约是5。

3 个答案:

答案 0 :(得分:2)

1)strapplyc / read.pattern 假设DF,如最后的注释,定义模式pat,这是一个相当简单的正则表达式,由匹配BINDING,空格和捕获数字组。现在计算列名cn,方法是使用strapplyc将匹配项提取到每行pat,使用lengths计算它们,然后找出这些列的最大值列数。用它来构造列名cn。在下一行中,使用read.pattern读取数据,并使用刚才计算的列名称使用相同的模式pat

library(gsubfn)

pat <- "BINDING (\\d+)"
cn <- paste0("Bindsite", seq_len(max(lengths(strapplyc(DF[[1]], pat)))))
read.pattern(text = DF[[1]], pattern = pat, fill = TRUE, col.names = cn)

,并提供:

  Bindsite1 Bindsite2
1       346        28
2        12        NA

2)strapply 上面的变化是一行更长但是单独的行相对简单并且它只进行一次匹配(而不是两次)。它使用与{1}具有相同正则表达式的strapply来获取列表,每个列表的元素是一行上匹配数字的向量。然后,它计算每个这样的向量的最大长度,并将s的每个这样的元素扩展到该长度。最后,它将它们全部组合在一起并设置列名称。结果是数字矩阵m

library(gsubfn)

s <- strapply(DF[[1]], "BINDING (\\d+)", as.numeric)
mx <- max(lengths(s))
m <- do.call("rbind", lapply(s, "length<-", mx))
colnames(m) <- paste0("Bindsite", 1:ncol(m))

,并提供:

> m
     Bindsite1 Bindsite2
[1,]       346        28
[2,]        12        NA

注意:可重复形式的输入DF假定为:

Lines <- "Binding site
BINDING 346 346 jakdjf;aj [0984]. BINDING 28 28 jdalkjda.
BINDING 12 12 jklbasdjf;la."
DF <- read.table(text = Lines, header = TRUE, sep = "\1", as.is = TRUE)

答案 1 :(得分:1)

假设您开始使用长度为2的字符向量,则基本R替代

# extract a list of numeric vectors, one per element in the character vector
myList <- lapply(regmatches(temp, gregexpr("BINDING \\d+", temp)),
                 function(x) as.numeric(sub("BINDING ", "", x, fixed=TRUE)))
# get max length of numeric vectors
maxL <- max(lengths(myList))

# construct data.frame and add names with setNames
setNames(data.frame(t(sapply(myList, function(x) x[seq_len(maxL)]))),
         paste0("binding", seq_len(maxL)))

这将返回一个包含两列的data.frame。

  binding1 binding2
1      346       28
2       12       NA

数据

temp <- 
c("BINDING 346 346 jakdjf;aj [0984]. BINDING 28 28 jdalkjda", 
"BINDING 12 12 jklbasdjf;la")

答案 2 :(得分:0)

1)目前尚不清楚数据集的结构。因此,我们使用readLines阅读它,在填充str_extract_all之后使用rbindlist元素在'BINDING'之后提取数字,因为元素的长度小于最大长度。

NA

注意:除library(stringr) lst <- lapply(str_extract_all(lines[-1], "(?<=BINDING\\s)\\d+\\s*"), as.numeric) m1 <- do.call(rbind, lapply(lst, `length<-`, max(lengths(lst)))) colnames(m1) <- paste0(sub("\\s+", "", lines[1]), seq_len(ncol(m1))) m1 # Bindingsite1 Bindingsite2 #[1,] 346 28 #[2,] 12 NA

外,不使用外部包

数据

stringr