How to remove '.' from column content in a dataframe? - r

I have a dataframe containing a number of ensembl gene annotations, the DF looks like this:
geneID
1 ENSG00000000005.5
2 ENSG00000001561.6
3 ENSG00000002726.18
4 ENSG00000005302.16
5 ENSG00000005379.14
6 ENSG00000006116.3
so I would like to delete that "." and the numbers at the end of every ID. In total I have 11224 rows.
I tried using the gsub command gsub(".","",colnames(dataframe)) but this is not helping.
Any suggestions?
Thank you in advance.

If we need the . at the end, capture the characters until the . (as . is a metacharacter meaning any character, escape it (\\) ) followed by one or more numbers (\\d+) until the end of the string and replace with the backreference (\\1) of the captured group
df1$geneID <- sub("^(.*\\.)\\d+$", "\\1", df1$geneID)
If the intention is to remove the . with the numbers after that, match the dot followed by one or more numbers and replace with blank ("")
df1$geneID <- sub("\\.\\d+", "", df1$geneID)
df1$geneID
#[1] "ENSG00000000005" "ENSG00000001561" "ENSG00000002726" "ENSG00000005302"
#[5] "ENSG00000005379" "ENSG00000006116"

You can use following code to remove alphanumeric after '.'
gsub("\\..*", "", df$geneID)

Related

Substitute and drop characters in column names

I have the following names of variables:
vars <- c("var-1.caps(12, For]","var2(5,For]","var-3.tree.(15, For]","var-3.tree.(30, For]")
I need to clean these names in order to get the following result:
clean_vars <- c("var1.caps_12_For","var2_5_For","var3.tree_15_For","var3.tree_30_For")
So, basically I would like to drop -, ( and ].
I was using this approach:
gsub("\\(.*\\]","",vars)
But it drops everything between ( and ]. It neither drops the symbol -.
We can capture as a group. Match the pattern for a . if it exists followed by a ( (metacharacters - so escape \\), followed by one or more digits (\\d+) captured as a group ((...)), followed by a , and zero or more spaces (\\s*), then capture the word ([A-Za-z]+) as second capture group. In the replacement, specify the backreference (\\1, \\2) of the capture group along with _ to get the expected output
out <- sub("\\.?\\((\\d+),\\s*([A-Za-z]+)\\]$", "_\\1_\\2", vars)
out
#[1] "var-1.caps_12_For" "var2_5_For" "var-3.tree_15_For" "var-3.tree_30_For"
sub('-', '', out)
#[1] "var1.caps_12_For" "var2_5_For" "var3.tree_15_For" "var3.tree_30_For"

Extract a year number from a string that is surrounded by special characters

What's a good way to extract only the number 2007 from the following string:
some_string <- "1_2_start_2007_3_end"
The pattern to detect the year number in my case would be:
4 digits
surrounded by "_"
I am quite new to using regular expressions. I tried the following:
regexp <- "_+[0-9]+_"
names <- str_extract(files, regexp)
But this does not take into account that there are always 4 digits and outputs the underlines as well.
You may use a sub option, too:
some_string <- "1_2_start_2007_3_end"
sub(".*_(\\d{4})_.*", "\\1", some_string)
See the regex demo
Details
.* - any 0+ chars, as many as possible
_ - a _ char
(\\d{4}) - Group 1 (referred to via \1 from the replacement pattern): 4 digits
_.* - a _ and then any 0+ chars up to the end of string.
NOTE: akrun's str_extract(some_string, "(?<=_)\\d{4}") will extract the leftmost occurrence and my sub(".*_(\\d{4})_.*", "\\1", some_string) will extract the rightmost occurrence of a 4-digit substring enclosed with _. For my my solution to return the leftmost one use a lazy quantifier with the first .: sub(".*?_(\\d{4})_.*", "\\1", some_string).
R test:
some_string <- "1_2018_start_2007_3_end"
sub(".*?_(\\d{4})_.*", "\\1", some_string) # leftmost
## -> 2018
sub(".*_(\\d{4})_.*", "\\1", some_string) # rightmost
## -> 2007
We can use regex lookbehind to specify the _ and extract the 4 digits that follow
library(stringr)
str_extract(some_string, "(?<=_)\\d{4}")
#[1] "2007"
If the pattern also shows - both before and after the 4 digits, then use regex lookahead as well
str_extract(some_string, "(?<=_)\\d{4}(?=_)")
#[1] "2007"
Just to get a non-regex approach out there, in which we split on _ and convert to numeric. All non-numbers will be coerced to NA, so we use !is.na to eliminate them. We then use nchar to count the characters, and pull the one with 4.
i1 <- as.numeric(strsplit(some_string, '_')[[1]])
i1 <- i1[!is.na(i1)]
i1[nchar(i1) == 4]
#[1] 2007
This is the quickest regex I could come up with:
\S.*_(\d{4})_\S.*
It means,
any number of non-space characters,
then _
followed by four digits (d{4})
above four digits is your year captured using ()
another _
any other gibberish non space string
Since, you mentioned you're new, please test this and all other answers at https://regex101.com/, pretty good to learn regex, it explains in depth what your regex is actually doing.
If you just care about (year) then below regex is enough:
_(\d{4})_

How to take only that part of a string which occurs before a pattern of 2 dots?

I used a code of regular expressions which only took stuff before the 2nd occurrence of a dot. The following is the code:-
colnames(final1)[i] <- gsub("^([^.]*.[^.]*)..*$", "\\1", colnames(final)[i])
But now i realized i wanted to take the stuff before the first occurrence of a pattern of 2 dots.
I tried
gsub(",.*$", "", colnames(final)[i]) (changed the , to ..)
gsub("...*$", "", colnames(final)[i])
But it didn't work
The example to try on
KC1.Comdty...PX_LAST...USD......Comdty........
converted to
KC1.Comdty.
or
"LIT.US.Equity...PX_LAST...USD......Comdty........"
to
"LIT.US.Equity."
Can anyone suggest anything?
Thanks
We could use sub to match 2 or more dots followed by other characters and replace it with blank
sub("\\.{2,}.*", "", str1)
#[1] "KC1.Comdty" "LIT.US.Equity"
The . is a metacharacter implying any character. So, we need to escape (\\.) to get the literal meaning of the character
data
str1 <- c("KC1.Comdty...PX_LAST...USD......Comdty.......", "LIT.US.Equity...PX_LAST...USD......Comdty........")
Another solution with strsplit:
str1 <- c("KC1.Comdty...PX_LAST...USD......Comdty.......", "LIT.US.Equity...PX_LAST...USD......Comdty........")
sapply(strsplit(str1, "\\.{2}\\w"), "[", 1)
# [1] "KC1.Comdty." "LIT.US.Equity."
To also include the dot at the end with #akrun's answer, one can do:
sub("\\.{2}\\w.*", "", str1)
# [1] "KC1.Comdty." "LIT.US.Equity."

Characters before/after a symbol

I have the following string in R: "xxx, yyy. zzz"
I want to get the yyy part only, which are in between "," and "."
I don't want to use regex.
I searched half a day, found many string functions in R but none which deal with "cut before/after a character" function.
Is there such?
We can use gsub to match zero or more characters that are not a , ([^,]*) from the start (^) of the string followed by a , followed by zero or more spaces (\\s*) or (!) a dot (\\. - it is a metacharacter meaning any character so it is escaped) followed by other characters (.*) until the end of the string ($) and replace it with blank ("")
gsub("^[^,]*,\\s*|\\..*$", "", str1)
#[1] "yyy"
If we don't need regex then strsplit the string by , followed by zero or more spaces or with a . and select the second entry after converting the list output to vector ([[1]])
strsplit(str1, ",\\s*|\\.")[[1]][2]
#[1] "yyy"
data
str1 <- "xxx, yyy. zzz"
It could be that this suffices:
unlist(strsplit("xxx, yyy. zzz","[,.]"))[2] # get yyy with space, or:
gsub(" ","",unlist(strsplit("xxx, yyy. zzz","[,.]")))[2] # remove space

Extract Between Parts of a String

I have a string of names in the following format:
names <- c("Q-1234-1", "Q-1234-2", "Q-1234-1-8", "Q-1234-2-8")
I am trying to extract the single digit after the second hyphen. There are instances where there will be a third hyphen and an additional digit at the end of the name. The desired output is:
1, 2, 1, 2
I assume that I will need to use sub/gsub but am not sure where to start. Any suggestions?
We can use sub to match the pattern of zero or more characters that are not a - ([^-]*) from the start (^) of the string followed by a - followed by zero or more characters that are not a - followed by a - and the number that follows being captured as a group. In the replacement, we use the backreference of the captured group (\\1)
as.integer(sub("^[^-]*-[^-]*-(\\d).*", "\\1", names))
#[1] 1 2 1 2
Or this can be modified to
as.integer(sub("^([^-]*-){2}(\\d).*", "\\2", names))
#[1] 1 2 1 2
Here's an alternative using stringr
library("stringr")
names <- c("Q-1234-1", "Q-1234-2", "Q-1234-1-8", "Q-1234-2-8")
output = str_split_fixed(names, pattern = "-", n = 4)[,3]

Resources