<p>Maybe this is what you're after, using <code>str_locate</code> to find the <em>start</em> and <em>end</em> of the pattern</p>
<pre><code>library(stringr)

GCbackbone &lt;- function(vec, pattern = &quot;GAGTA&quot;, bf=1, af=1) sapply(vec, \(x){ 
  m &lt;- str_locate(x, pattern)
  if(any(is.na(m))) c(NA, NA)
  c(before=substr(x, m[,&quot;start&quot;] - (bf - 1) - 1, m[,&quot;start&quot;] - 1), 
    after=substr(x, m[,&quot;end&quot;] + 1, m[,&quot;end&quot;] + (af - 1) + 1))}, USE.NAMES=F)
</code></pre>
<pre><code>GCbackbone(myDataFrame$s2m, &quot;GCCG&quot;, 2, 1)
       [,1] [,2] [,3] [,4] [,5] [,6]
before &quot;AC&quot; NA   NA   NA   &quot;AA&quot; &quot;AC&quot;
after  &quot;A&quot;  NA   NA   NA   &quot;A&quot;  &quot;A&quot;
</code></pre>
<p>Keep in mind that it only considers the first match within a string. Use <code>str_locate_all</code> to get all matches.</p>

CC BY-SA 4.0
2024-08-18T00:06:53.940Z
2024-08-18T00:06:53.940Z
Andre Wildberg
<p>I developed an R function to find a given pattern and check for before and after that pattern, I asked the function to return NA, when the pattern is not found, but now the function returns 0000000 instead of NA when there is no pattern.</p>
<pre><code>GCbackbone &lt;- function(x,pattern = &quot;GAGTA&quot;,befor=1,after=1) {
  match &lt;- regexpr(pattern,x)
  if(match[1]==-1){
    return(c(NA,NA))
  }
  n &lt;- nchar(pattern)
  af &lt;- substr(x,match[1]+n+after-1,n+match[1]+after-1)
  bef &lt;- substr(x,match[1]-befor,match[1]-befor)
  return(c(bef,af))
}
vec &lt;- myDataFrame$squence
befor1 &lt;- sapply(vec,GCbackbone,befor = 1,after = 1) |&gt; unname() |&gt;
  apply(2,paste0,collapse = &quot;&quot;)
befor2 &lt;- sapply(vec,GCbackbone,befor = 2,after = 2) |&gt; unname() |&gt; 
  apply(2,paste0,collapse = &quot;&quot;)
befor3 &lt;- sapply(vec,GCbackbone,befor = 3,after = 5) |&gt; unname() |&gt; 
  apply(2,paste0,collapse = &quot;&quot;)
befor4 &lt;- sapply(vec,GCbackbone,befor = 4,after = 6) |&gt; unname() |&gt; 
  apply(2,paste0,collapse = &quot;&quot;)
befor6 &lt;- sapply(vec,GCbackbone,befor = 6,after = 9) |&gt; unname() |&gt; 
  apply(2,paste0,collapse = &quot;&quot;)
befor7 &lt;- sapply(vec,GCbackbone,befor = 7,after = 10) |&gt; unname() |&gt; 
  apply(2,paste0,collapse = &quot;&quot;)
befor8 &lt;- sapply(vec,GCbackbone,befor = 8,after = 11) |&gt; unname() |&gt; 
  apply(2,paste0,collapse = &quot;&quot;)


res1 &lt;- as.numeric(befor1 %in% c(&quot;GC&quot;,&quot;CG&quot;))
res2 &lt;- as.numeric(befor2 %in% c(&quot;GC&quot;,&quot;CG&quot;))
res3 &lt;- as.numeric(befor3 %in% c(&quot;GC&quot;,&quot;CG&quot;))
res4 &lt;- as.numeric(befor4 %in% c(&quot;GC&quot;,&quot;CG&quot;))
res6 &lt;- as.numeric(befor6 %in% c(&quot;GC&quot;,&quot;CG&quot;))
res7 &lt;- as.numeric(befor7 %in% c(&quot;GC&quot;,&quot;CG&quot;))
res8 &lt;- as.numeric(befor8 %in% c(&quot;TG&quot;,&quot;GT&quot;))

myDataFrame$GCresult &lt;- cbind(res1,res2,res3,res4,res6,res7,res8) |&gt; apply(1,paste0,collapse = &quot;&quot;)
</code></pre>
<p>First 6 rows of <code>myDataFrame</code>:</p>
<pre class="lang-r prettyprint-override"><code>dput(head(myDataFrame))

structure(list(subject.acc.ver = c(&quot;KP036503.1&quot;, &quot;KP036502.1&quot;, 
&quot;MW791835.&quot;, &quot;MZ461455.1&quot;, &quot;MZ461454.1&quot;, &quot;MZ461453.1&quot;), s2m = c(&quot;GGCCACGCCGAGTAGGATCGAGGGTA&quot;, 
&quot;GGCCACGCTGAGTAGGATCGAGGGTA&quot;, &quot;GGCCACGACGAGTAGGATCGAGGGTA&quot;, &quot;GGCCACRCCGAGTAGGATCGAGGGTA&quot;, 
&quot;GGCAAAGCCGAGTAGGATCGAGGGTA&quot;, &quot;GGCCACGCCGAGTAGGATCGAGGAAA&quot;), 
    GCresult = c(&quot;1111111&quot;, &quot;0111111&quot;, &quot;1011111&quot;, &quot;1101111&quot;, 
    &quot;1110011&quot;, &quot;1111100&quot;)), row.names = c(NA, 6L), class = &quot;data.frame&quot;)
</code></pre>

CC BY-SA 4.0
2024-08-15T21:13:36.967Z
Can you add a sample of "MyDataFrame", or of the resulting vectors?
Max_IT
CC BY-SA 4.0
2024-08-16T16:47:04.773Z
1 KP696543.1 GGCCACGCCGAGTAGGATCGAGGGTA 1111111 
2 KP046442.1 GGCCACGCTGAGTAGGATCGAGGGTA 0111111 
3 MW5617835. GGCCACGACGAGTAGGATCGAGGGTA 1011111 
4 MZ4634235.1 GGCCACRCCGAGTAGGATCGAGGGTA 1101111 
5 MZ461454.1 GGCAAAGCCGAGTAGGATCGAGGGTA 1110011 
6 MZ461453.1 GGCCACGCCGAGTAGGATCGAGGAAA 1111100
Farzad Beikpour
CC BY-SA 4.0
2024-08-16T17:31:33.850Z
That does not help. What is the output to `dput(head(MyDataFrame)`? Edit your post and add the content there with code formatting.
Ram RS
CC BY-SA 4.0
2024-08-16T17:49:00.930Z
structure(list(subject.acc.ver = c("KP036503.1", "KP036502.1", 
"MW791835.", "MZ461455.1", "MZ461454.1", "MZ461453.1"), s2m = c("GGCCACGCCGAGTAGGATCGAGGGTA", 
"GGCCACGCTGAGTAGGATCGAGGGTA", "GGCCACGACGAGTAGGATCGAGGGTA", "GGCCACRCCGAGTAGGATCGAGGGTA", 
"GGCAAAGCCGAGTAGGATCGAGGGTA", "GGCCACGCCGAGTAGGATCGAGGAAA"), 
    GCresult = c("1111111", "0111111", "1011111", "1101111", 
    "1110011", "1111100")), row.names = c(NA, 6L), class = "data.frame")
Farzad Beikpour
CC BY-SA 4.0
2024-08-17T22:30:30.370Z
`regexpr` is vectorized, so if you do `match <- regexpr(pattern,x)` you get a vector but you test for a scalar with `match[1]`.
Andre Wildberg
<r>
R function does not return NA when it should
# R function does not return NA when it should

(Asked by: username_0 on 2024-08-15)

I developed an R function to find a given pattern and check for before and after that pattern, I asked the function to return NA, when the pattern is not found, but now the function returns 0000000 instead of NA when there is no pattern.
GCbackbone <- function(x,pattern = "GAGTA",befor=1,after=1) {
  match <- regexpr(pattern,x)
  if(match[1]==-1){
    return(c(NA,NA))
  }
  n <- nchar(pattern)
  af <- substr(x,match[1]+n+after-1,n+match[1]+after-1)
  bef <- substr(x,match[1]-befor,match[1]-befor)
  return(c(bef,af))
}
vec <- myDataFrame$squence
befor1 <- sapply(vec,GCbackbone,befor = 1,after = 1) |> unname() |>
  apply(2,paste0,collapse = "")
befor2 <- sapply(vec,GCbackbone,befor = 2,after = 2) |> unname() |> 
  apply(2,paste0,collapse = "")
befor3 <- sapply(vec,GCbackbone,befor = 3,after = 5) |> unname() |> 
  apply(2,paste0,collapse = "")
befor4 <- sapply(vec,GCbackbone,befor = 4,after = 6) |> unname() |> 
  apply(2,paste0,collapse = "")
befor6 <- sapply(vec,GCbackbone,befor = 6,after = 9) |> unname() |> 
  apply(2,paste0,collapse = "")
befor7 <- sapply(vec,GCbackbone,befor = 7,after = 10) |> unname() |> 
  apply(2,paste0,collapse = "")
befor8 <- sapply(vec,GCbackbone,befor = 8,after = 11) |> unname() |> 
  apply(2,paste0,collapse = "")


res1 <- as.numeric(befor1 %in% c("GC","CG"))
res2 <- as.numeric(befor2 %in% c("GC","CG"))
res3 <- as.numeric(befor3 %in% c("GC","CG"))
res4 <- as.numeric(befor4 %in% c("GC","CG"))
res6 <- as.numeric(befor6 %in% c("GC","CG"))
res7 <- as.numeric(befor7 %in% c("GC","CG"))
res8 <- as.numeric(befor8 %in% c("TG","GT"))

myDataFrame$GCresult <- cbind(res1,res2,res3,res4,res6,res7,res8) |> apply(1,paste0,collapse = "")

First 6 rows of myDataFrame:
dput(head(myDataFrame))

structure(list(subject.acc.ver = c("KP036503.1", "KP036502.1", 
"MW791835.", "MZ461455.1", "MZ461454.1", "MZ461453.1"), s2m = c("GGCCACGCCGAGTAGGATCGAGGGTA", 
"GGCCACGCTGAGTAGGATCGAGGGTA", "GGCCACGACGAGTAGGATCGAGGGTA", "GGCCACRCCGAGTAGGATCGAGGGTA", 
"GGCAAAGCCGAGTAGGATCGAGGGTA", "GGCCACGCCGAGTAGGATCGAGGAAA"), 
    GCresult = c("1111111", "0111111", "1011111", "1101111", 
    "1110011", "1111100")), row.names = c(NA, 6L), class = "data.frame")

**Tags:** r
> **Comments:**
> **username_1**: Can you add a sample of "MyDataFrame", or of the resulting vectors?  
> **username_0**: 1 KP696543.1 GGCCACGCCGAGTAGGATCGAGGGTA 1111111  2 KP046442.1 GGCCACGCTGAGTAGGATCGAGGGTA 0111111  3 MW5617835. GGCCACGACGAGTAGGATCGAGGGTA 1011111  4 MZ4634235.1 GGCCACRCCGAGTAGGATCGAGGGTA 1101111  5 MZ461454.1 GGCAAAGCCGAGTAGGATCGAGGGTA 1110011  6 MZ461453.1 GGCCACGCCGAGTAGGATCGAGGAAA 1111100  
> **username_2**: That does not help. What is the output to `dput(head(MyDataFrame)`? Edit your post and add the content there with code formatting.  
> **username_0**: structure(list(subject.acc.ver = c("KP036503.1", "KP036502.1",  "MW791835.", "MZ461455.1", "MZ461454.1", "MZ461453.1"), s2m = c("GGCCACGCCGAGTAGGATCGAGGGTA",  "GGCCACGCTGAGTAGGATCGAGGGTA", "GGCCACGACGAGTAGGATCGAGGGTA", "GGCCACRCCGAGTAGGATCGAGGGTA",  "GGCAAAGCCGAGTAGGATCGAGGGTA", "GGCCACGCCGAGTAGGATCGAGGAAA"),      GCresult = c("1111111", "0111111", "1011111", "1101111",      "1110011", "1111100")), row.names = c(NA, 6L), class = "data.frame")  
> **username_3**: `regexpr` is vectorized, so if you do `match <- regexpr(pattern,x)` you get a vector but you test for a scalar with `match[1]`.  

---

## 1 answers

### Answer by username_3 on 2024-08-18. Score: 2

Maybe this is what you're after, using str_locate to find the start and end of the pattern
library(stringr)

GCbackbone <- function(vec, pattern = "GAGTA", bf=1, af=1) sapply(vec, \(x){ 
  m <- str_locate(x, pattern)
  if(any(is.na(m))) c(NA, NA)
  c(before=substr(x, m[,"start"] - (bf - 1) - 1, m[,"start"] - 1), 
    after=substr(x, m[,"end"] + 1, m[,"end"] + (af - 1) + 1))}, USE.NAMES=F)

GCbackbone(myDataFrame$s2m, "GCCG", 2, 1)
       [,1] [,2] [,3] [,4] [,5] [,6]
before "AC" NA   NA   NA   "AA" "AC"
after  "A"  NA   NA   NA   "A"  "A"

Keep in mind that it only considers the first match within a string. Use str_locate_all to get all matches.


---

