Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-08-18T00:06:53.940Z
Answers.LastActivityDate: 2024-08-18T00:06:53.940Z
Answers.UserDisplayName: Andre Wildberg
Body: <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>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-08-15T21:13:36.967Z
Comments.Text: Can you add a sample of "MyDataFrame", or of the resulting vectors?
Comments.UserDisplayName: Max_IT
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-08-16T16:47:04.773Z
Comments.Text: 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
Comments.UserDisplayName: Farzad Beikpour
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-08-16T17:31:33.850Z
Comments.Text: That does not help. What is the output to `dput(head(MyDataFrame)`? Edit your post and add the content there with code formatting.
Comments.UserDisplayName: Ram RS
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-08-16T17:49:00.930Z
Comments.Text: 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")
Comments.UserDisplayName: Farzad Beikpour
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-08-17T22:30:30.370Z
Comments.Text: `regexpr` is vectorized, so if you do `match <- regexpr(pattern,x)` you get a vector but you test for a scalar with `match[1]`.
Comments.UserDisplayName: Andre Wildberg
Tags: <r>
Title: R function does not return NA when it should
ThreadText: # 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`:
  
  ```r
  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.
  
  
  ---
  
  