Convert binary vector to decimal - r

I have a vector of a binary string:
a<-c(0,0,0,1,0,1)
I would like to convert this vector into decimal.
I tried using the compositions package and the unbinary() function, however, this solution and also most others that I have found on this site require g-adic string as input argument.
My question is how can I convert a vector rather than a string to decimal?
to illustrate the problem:
library(compositions)
unbinary("000101")
[1] 5
This gives the correct solution, but:
unbinary(a)
unbinary("a")
unbinary(toString(a))
produces NA.

You could try this function
bitsToInt<-function(x) {
packBits(rev(c(rep(FALSE, 32-length(x)%%32), as.logical(x))), "integer")
}
a <- c(0,0,0,1,0,1)
bitsToInt(a)
# [1] 5
here we skip the character conversion. This only uses base functions.
It is likely that
unbinary(paste(a, collapse=""))
would have worked should you still want to use that function.

There is a one-liner solution:
Reduce(function(x,y) x*2+y, a)
Explanation:
Expanding the application of Reduce results in something like:
Reduce(function(x,y) x*2+y, c(0,1,0,1,0)) = (((0*2 + 1)*2 + 0)*2 + 1)*2 + 0 = 10
With each new bit coming next, we double the so far accumulated value and add afterwards the next bit to it.
Please also see the description of Reduce() function.

If you'd like to stick to using compositions, just convert your vector to a string:
library(compositions)
a <- c(0,0,0,1,0,1)
achar <- paste(a,collapse="")
unbinary(achar)
[1] 5

This function will do the trick.
bintodec <- function(y) {
# find the decimal number corresponding to binary sequence 'y'
if (! (all(y %in% c(0,1)))) stop("not a binary sequence")
res <- sum(y*2^((length(y):1) - 1))
return(res)
}

Related

Replace cos^..(...) by (cos(...))^

I run WolframAlpha through R
Wolfram Alpha API from R
My problem is, that I need to convert wolfram output to R expression.
I have added "*" where it's needed, there's another issue - converting of goniometric functions.
Example:
I have: cos^3(5 + 2*x)
I need to get: (cos(5 + 2*x))^3
Could somebody give me a hint how to achieve the expression? Or is there any package for conversion? Or does somebody suggest any other way?
SOLUTION by #G. Grothendieck
sub("(sin|cos|tan)\\^(\\(?-?\\d+\\)?)", "(function(x) \\1(x)^\\2)", 'cos^3(5 + 2*x)')
Define a function called cos^3, insert backticks into the original string around it and evaluate.
`cos^3` <- function(x) cos(x)^3
s <- sub("cos^3", "`cos^3`", input_string, fixed = TRUE) # `cos^3`(5 + 2*x)
x <- .5 # test value for x
eval(parse(text = s))
## [1] 0.8852069
This could be generalized a bit if need be like this:
input_string <- "cos^(3)(5+2*x)"
sub("(sin|cos|tan)\\^(\\(?-?\\d+\\)?)", "(function(x) \\1(x)^\\2)", input_string)
## [1] "(function(x) cos(x)^(3))(5+2*x)"
I think that you have the original formula as a string and want to evaluate it in R (with the modified syntax). You can change the formula using sub and then evaluate it using parse and eval.
F1 = "cos^3(5 + 2*x)"
F2 = sub("(.*)(\\^\\d)(.*)", "\\1\\3\\2", F1)
F2
[1] "cos(5 + 2*x)^3"
x = 1:4
eval(parse(text=F2))
[1] 4.284944e-01 -7.563824e-01 8.668527e-08 7.472458e-01
Here's a solution to your specific case, which should help getting started on a more general solution (this will work for strings of the form 'cos^X(Y)' where X is some digits and Y is an arithmetic expression):
input_string <- 'cos^3(5 + 2*x)'
desired_output_string <- '(cos(5 + 2*x))^3'
convert_string <- function(s){
return(gsub('(cos)(\\^\\d+)(\\([a-z0-9+* ]+\\))', '(\\1\\3)\\2', s))
}
output_string <- convert_string(input_string)
if (output_string == desired_output_string){
message('the output matches!')
} else { message('try again </3') }
And then if you need to actually evaluate the string, you can use eval(parse(text=output_string)), making sure that all variables it contains have values:
x <- 5
eval(parse(text=output_string))
## -0.4384354

Finding the position of a character within a string

I am trying to find the equivalent of the ANYALPHA SAS function in R. This function searches a character string for an alphabetic character, and returns the first position at which at which the character is found.
Example: looking at the following string '123456789A', the ANYALPHA function would return 10 since first alphabetic character is at position 10 in the string. I would like to replicate this function in R but have not been able to figure it out. I need to search for any alphabetic character regardless of case (i.e. [:alpha:])
Thanks for any help you can offer!
Here's an anyalpha function. I added a few extra features. You can specify the maximum amount of matches you want in the n argument, it defaults to 1. You can also specify if you want the position or the value itself with value=TRUE:
anyalpha <- function(txt, n=1, value=FALSE) {
txt <- as.character(txt)
indx <- gregexpr("[[:alpha:]]", txt)[[1]]
ret <- indx[1:(min(n, length(indx)))]
if(value) {
mapply(function(x,y) substr(txt, x, y), ret, ret)
} else {ret}
}
#test
x <- '123A56789BC'
anyalpha(x)
#[1] 4
anyalpha(x, 2)
#[1] 4 10
anyalpha(x, 2, value=TRUE)
#[1] "C" "A"

Converting a string to a number in R

I'm having trouble with simply writing a function that turns a string representation of a number into a decimal representation. To boil the issue down to essentials, consider the following function:
f <- function(x) {
y <- as.numeric(x)
return(y)
}
When I apply this function to the string "47.418" I get back 47.42, but what I want to get back is 47.418. It seems like the return value is being rounded for some reason.
Any suggestions would be appreciated
You have done something to your print options. I get no rounding:
> f <- function(x) { y <- as.numeric(x); return(y) }
> f(47.418)
[1] 47.418
?options
The default value for digits is 7:
> options("digits")
$digits
[1] 7
Further questions should be accompanied by dput() on the object in question.

R convert text field to function

I want to use information from a field and include it in a R function, e.g.:
data #name of the data.frame with only one raw
"(if(nclusters>0){OptmizationInputs[3,3]*beta[1]}else{0})" # this is the raw
If I want to use this information inside a function how could I do it?
Another example:
A=c('x^2')
B=function (x) A
B(2)
"x^2" # this is the return. I would like to have the return something like 2^2=4.
Use body<- and parse
A <- 'x^2'
B <- function(x) {}
body(B) <- parse(text = A)
B(3)
## [1] 9
There are more ideas here
Another option using plyr:
A <- 'x^2'
library(plyr)
body(B) <- as.quoted(A)[[1]]
> B(5)
[1] 25
A <- "x^2"; x <- 2
BB <- function(z){ print( as.expression(do.call("substitute",
list( parse(text=A)[[1]], list(x=eval(x) ) )))[[1]] );
cat( "is equal to ", eval(parse(text=A)))
}
BB(2)
#2^2
#is equal to 4
Managing expressions in R is very weird. substitute refuses to evaluate its first argument so you need to use do.call to allow the evaluation to occur before the substitution. Furthermore the printed representation of the expressions hides their underlying representation. Try removing the fairly cryptic (to my way of thinking) [[1]] after the as.expression(.) result.

Replace non-ascii chars with a defined string list without a loop in R

I want to replace non-ascii characters (for now, only spanish), by their ascii equivalent. If I have "á", I want to replace it with "a" and so on.
I built this function (works fine), but I don't want to use a loop (including internal loops like sapply).
latin2ascii<-function(x) {
if(!is.character(x)) stop ("input must be a character object")
require(stringr)
mapL<-c("á","é","í","ó","ú","Á","É","Í","Ó","Ú","ñ","Ñ","ü","Ü")
mapA<-c("a","e","i","o","u","A","E","I","O","U","n","N","u","U")
for(y in 1:length(mapL)) {
x<-str_replace_all(x,mapL[y],mapA[y])
}
x
}
Is there an elegante way to solve it? Any help, suggestion or modification is appreciated
gsubfn() in the package of the same name is really nice for this sort of thing:
library(gsubfn)
# Create a named list, in which:
# - the names are the strings to be looked up
# - the values are the replacement strings
mapL <- c("á","é","í","ó","ú","Á","É","Í","Ó","Ú","ñ","Ñ","ü","Ü")
mapA <- c("a","e","i","o","u","A","E","I","O","U","n","N","u","U")
# ll <- setNames(as.list(mapA), mapL) # An alternative to the 2 lines below
ll <- as.list(mapA)
names(ll) <- mapL
# Try it out
string <- "ÍÓáÚ"
gsubfn("[áéíóúÁÉÍÓÚñÑüÜ]", ll, string)
# [1] "IOaU"
Edit:
G. Grothendieck points out that base R also has a function for this:
A <- paste(mapA, collapse="")
L <- paste(mapL, collapse="")
chartr(L, A, "ÍÓáÚ")
# [1] "IOaU"
I like the version by Josh, but I thought I might add another 'vectorized' solution. It returns a vector of unaccented strings. It also only relies on the base functions.
x=c('íÁuÚ','uíÚÁ')
mapL<-c("á","é","í","ó","ú","Á","É","Í","Ó","Ú","ñ","Ñ","ü","Ü")
mapA<-c("a","e","i","o","u","A","E","I","O","U","n","N","u","U")
split=strsplit(x,split='')
m=lapply(split,match,mapL)
mapply(function(split,m) paste(ifelse(is.na(m),split,mapA[m]),collapse='') , split, m)
# "iAuU" "uiUA"

Resources