Ascending order of vector of numeric characters - r

I have a vector of numbers of type character.
x = c("5","-.5","-.1",".01",".1","1","3")
Is there a quick and easy way to order this character vector using the numeric value of each character? I can't find a clean way to do this.
So for instance, I want a function
x <- characterOrder(x)
With output:
c("-.5","-.1",".01",".1","1","3", "5")
Thank you!

You can do this in base R using the order function and the as.numeric when you order it by the as.numeric value.
x = c("5","-.5","-.1",".01",".1","1","3")
x[order(as.numeric(x))]
[1] "-.5" "-.1" ".01" ".1" "1" "3" "5"
If you want this in a function:
characterOrder <- function(x) {
return(x[order(as.numeric(x))])
}

You could try mixedsort from gtools
library(gtools)
mixedsort(x)
#[1] "-.5" "-.1" ".01" ".1" "1" "3" "5"

Related

Specific Permutations in R

I am trying to create permutations of the alphabet {0,1,2,3} using combinat::permn.
The thing is that I want each one of the permutations to be converted to the form of '%s-%s-%s'..etc and to be stored in a list. For example,
> library(combinat)
> permn(numbers[1:4])
[[1]]
[1] "0" "1" "2" "3"
[[2]]
[1] "0" "1" "3" "2"
.
.
. and so on
But I want to convert the output for all permutations into a list of string sequences of my specific format, i.e. '0-1-2-3', '0-1-3-2 etc.
Use lapply to apply paste on each of the vectors and collapse them with the delimiter you want (in this case "-").
lapply(permn(0:3), paste, collapse = "-")
If you just want the output as a vector instead of a list you could use sapply in place of lapply

Convert an integer to a string in R

I have an integer
a <- (0:3)
And I would like to convert it to a character string that looks like this
b <- "(0:3)"
I have tried
as.character(a)
[1] "0" "1" "2" "3"
and
toString(a)
[1] "0, 1, 2, 3"
But neither do exactly what I need to do.
Can anyone help me get from a to b?
Many thanks in advance!
paste0("(", min(a), ":", max(a), ")")
"(0:3)"
Or more concisely with sprintf():
sprintf("(%d:%d)", min(a), max(a))
One option is deparse and paste the brackets
as.character(glue::glue('({deparse(a)})'))
#[1] "(0:3)"
Another option would be to store as a quosure and then convert it to character
library(rlang)
a <- quo((0:3))
quo_name(a)
#[1] "(0:3)"
it can be evaluated with eval_tidy
eval_tidy(a)
#[1] 0 1 2 3

Parsing a factor string in R

I have a string ,
x = "[1,2,3]"
How can I get the elements 1 and 2 from the string?
I tried the strsplit but that seems a bit tricky. Then I tried splitting on "[", and that also did not seem easy.
You could use regex lookaround to extract the numbers
library(stringr)
str_extract_all(x, '(?<=\\[|,)\\d+(?=,)')[[1]]
#[1] "1" "2"
A base option, here we just remove the brackets and split by ,, though do note #MrFlick's comment.
strsplit(gsub("\\[|\\]", "", x), ",")[[1L]][1:2]
# [1] "1" "2"

Changing a column of a dataframe in R

I have a dataframe in R with a column with values as "s1-112", "s10-112", "s3656-112" etc. Now i want to change the values to only the part after "s" and before "-112" that is the number after s. is there a way?
You could use gsub here
x<-c("s1-112", "s10-112", "s3656-112")
gsub("s(.*)-112", "\\1", x)
# [1] "1" "10" "3656"
Or (using #MrFlick's data)
library(stringr)
str_extract(x, perl('\\d+(?=-)'))
#[1] "1" "10" "3656"

Sapply different than individual application of function

When applied individually to each element of the vector, my function gives a different result than using sapply. It's driving me nuts!
Item I'm using: this (simplified) list of arguments another function was called with:
f <- as.list(match.call()[-1])
> f
$ampm
c(1, 4)
To replicate this you can run the following:
foo <- function(ampm) {as.list(match.call()[-1])}
f <- foo(ampm = c(1,4))
Here is my function. It just strips the 'c(...)' from a string.
stripConcat <- function(string) {
sub(')','',sub('c(','',string,fixed=TRUE),fixed=TRUE)
}
When applied alone it works as so, which is what I want:
> stripConcat(f)
[1] "1, 4"
But when used with sapply, it gives something totally different, which I do NOT want:
> sapply(f, stripConcat)
ampm
[1,] "c"
[2,] "1"
[3,] "4"
Lapply doesn't work either:
> lapply(f, stripConcat)
$ampm
[1] "c" "1" "4"
And neither do any of the other apply functions. This is driving me nuts--I thought lapply and sapply were supposed to be identical to repeated applications to the elements of the list or vector!
The discrepency you are seeing, I believe, is simply due to how as.character coerces elements of a list.
x2 <- list(1:3, quote(c(1, 5)))
as.character(x2)
[1] "1:3" "c(1, 5)"
lapply(x2, as.character)
[[1]]
[1] "1" "2" "3"
[[2]]
[1] "c" "1" "5"
f is not a call, but a list whose first element is a call.
is(f)
[1] "list" "vector"
as.character(f)
[1] "c(1, 4)"
> is(f[[1]])
[1] "call" "language"
> as.character(f[[1]])
[1] "c" "1" "4"
sub attempts to coerce anything that is not a character into a chracter.
When you pass sub a list, it calls as.character on the list.
When you pass it a call, it calls as.character on that call.
It looks like for your stripConcat function, you would prefer a list as input.
In that case, I would recommend the following for that function:
stripConcat <- function(string) {
if (!is.list(string))
string <- list(string)
sub(')','',sub('c(','',string,fixed=TRUE),fixed=TRUE)
}
Note, however, that string is a misnomer, since it doesn't appear that you are ever planning to pass stripConcat a string. (not that this is an issue, of course)

Resources