Here are two examples using sapply, the first example works but the second example produces NA when x is large numbers. Can anyone help?
This works
x = 1:10
y = 5:15
sapply(x, function (i) min(abs(x[i]-y)))
But this does not work
x = 100000:100010
y = 5:15
sapply(x, function (i) min(abs(x[i]-y)))
The argument in the inline function in sapply is what each value of the first argument is inserted into, so in your case x[i] is not using i from 1 to 10 or whatever, but i from x[1] to x[end].
sapply(x,function(i) min(abs(i-y)))
That's what you're trying to do (take each element of x and subtract y from).
> x = 100000:100010
> y=5:15
> sapply(x,function(i) min(abs(i-y)))
# [1] 99985 99986 99987 99988 99989 99990 99991 99992 99993 99994 99995
When using i as you are using it, you'll need use a sequence in the X argument of sapply.
It's just like using i in a for loop
> x <- 1:10
> y <- 5:15
> sapply(seq_along(x), function(i) min(abs(x[i] - y)))
# [1] 4 3 2 1 0 0 0 0 0 0
> x <- 100000:100010
> y <- 5:15
> sapply(seq_along(x), function(i) min(abs(x[i] - y)))
# [1] 99985 99986 99987 99988 99989 99990 99991 99992 99993 99994 99995
Related
Im trying to write a function based on the Luhn algorithm (mod 10 algorithm), and I need a function that sums all integers > 9 in my number vector individually. E.g. 10 should sum to 1+0=1, and 19 should sum to 1+9=10. Example code:
nmr <- ("1_9_8_2_0_5_0_1_3_3_4_8")
nmr <- strsplit(nmr, "_")
nmr <- as.numeric(as.character(unlist(nmr[[1]])))
luhn_alg <- c(0,0,2,1,2,1,2,1,2,1,2,0)
x <- nmr*luhn_alg
x
[1] 0 0 16 2 0 5 0 1 6 3 8 0
sum(x)
[1] 41
I dont want the sum of x to equal 41. Instead I want the sum to equal: 0+0+1+6+2+0+5+0+1+6+3+8+0=32. I tried with a for loop but doesn't seem to get it right. Any help is much appreciated.
You may need to split the data again after multiplying it with luhn_alg.
Luhn_sum <- function(x, y) {
nmr <- as.numeric(unlist(strsplit(x, "_")))
x1 <- nmr*y
x1 <- as.numeric(unlist(strsplit(as.character(x1), '')))
sum(x1)
}
nmr <- ("1_9_8_2_0_5_0_1_3_3_4_8")
luhn_alg <- c(0,0,2,1,2,1,2,1,2,1,2,0)
Luhn_sum(nmr, luhn_alg)
#[1] 32
You can use substring and seq to create a vector of single digit numbers, then you only need to do a sum over them:
sum(
as.numeric(
substring(
paste(x, collapse = ""),
seq(1, sum(nchar(x)), 1),
seq(1, sum(nchar(x)), 1)
)
)
)
I'm trying to find all the numbers less than the square root of a inputted number.
I've written a function which will do this on entering one number. I have a sequence of numbers that I wish to evaluate the function for.
x <- 1:1000
z <- x^2+1
findy <- function(z){
y <<- seq(1, sqrt(z), 1)
}
n <- length(y)
for (i in 1:n) {
a[i] <- z[i] - y[i]
}
What I want to do is as follows.
Start with a vector z <- 1:1000
Create a new vector: w <- z^2 + 1
then for each number in this vector evaluate the function above.
Example
z <- c(1, 2, 3, 4)
w <- c(2, 5, 10, 17)
(this is where it gets tricky to describe the output)
y= 1
1,2
1,2,3
1,2,3,4
If that makes sense.
Then I would like to be able to pull out certain values of the above array.
If anyone could help then that would be amazing!
An option using sequence and split. The function returns a list.
f <- function(x) {
w <- x^2 + 1 # why do you need this line?
out <- sequence(sqrt(w)) # same as sequence(x)
split(out, cumsum(out == 1L))
}
out <- f(1:4)
out
#$`1`
#[1] 1
#
#$`2`
#[1] 1 2
#
#$`3`
#[1] 1 2 3
#
#$`4`
#[1] 1 2 3 4
To extract the vectors you can use $ or [[
out$`1` # output is a vector
[1] 1
or
out[2:3] # output is a list
#$`2`
#[1] 1 2
#$`3`
#[1] 1 2 3
See help("Extract") for details.
I need to write an algorithm that gives you any number n in base 3 in R. So far I wrote that :
vector <- c(10, 100, 1000, 10000)
ternary <- function(n) { while (n != 0) {
{q<- n%/%3}
{r <- n%%3}
{return(r)}
q<- n }
sapply(vector, ternary)}
I thought that by applying sapply( vector, ternary) it would give me all the r for any given n that I would put in ternary(n). My code still gives me the "last r" and I don't get why.
This is the straightforward implementation of what I have learned to do by hand in nth grade (don't remember exactly when).
base3 <- function(x){
y <- integer(0)
while(x >= 3){
r <- x %% 3
x <- x %/% 3
y <- c(r, y)
}
y <- c(x, y)
y
}
base3(10)
#[1] 1 0 1
base3(5)
#[1] 1 2
You ca use recursion:
base3 =function(x,y=NULL){
d = x %/% 3
r=c(x %% 3,y)
if(d>=3) base3(d,r)
else c(d,r)
}
base3(10)
[1] 1 0 1
> base3(100)
[1] 1 0 2 0 1
There are two vectors x and y. If x contains an NA I want the NA to be replaced by a value from "y" with the corresponding index. Here is some example code that works:
x <- c(1,2,3,NA,5)
y <- c(6,7,8,9,10)
combineVector <- function(x,y)
{
for (i in 1:length(x)){
if (is.na(x[i]) && !is.na(y[i])){
x[i] = y[i]
}
}
return (x)
}
combineVector(x,y)
# [1] 1 2 3 9 5
I could have written this in almost any programming language. Is there a more "R" way to perform this task?
x <- c(1,2,3,NA,5)
y <- c(6,7,8,9,10)
x[is.na(x)] <- y[is.na(x)]
See the above. using is.na() on x returns a logical vector where it is TRUE for the NA elements of x. Using these in the selector for X and Y will select only those NA elements. Using it in assignment will replace the NA elements from x with the corresponding ones from Y.
That will be much faster than looping as the vector gets large.
Try this code:
x[is.na(x)] <- y[is.na(x)]
By subsetting the x vector with is.na(x) you will be assigning only those values of x which are NA to the corresponding indices in the y vector.
To generate a new vector taking x and y as input, you can use the ifelse function:
x<-c(1,2,3,NA,NA)
y<-c(6,7,8,9,NA)
ifelse(is.na(x), y, x)
# [1] 1 2 3 9 NA
I have a situation similar to the following in R:
t <- (1:100) * 15
x <- c(134, 552, 864, 5000)
And I want to find for each value in x what the first index in t where t > x is. The following works using a loop:
y <- numeric(length(x))
for (i in 1:length(x))
y[i] <- which(t > x[i])[1]
# y
# [1] 9 37 58 NA
I was taught that loops in R are 'bad and slow', and while the time this takes to run for a reasonably large x is not a deal-breaker, I would like to know whether there is a better way?
If the objects are not too big (so that RAM is not limiting), you don't need *apply functions, which are just hidden loops.
temp <- outer(x,t,'<')
y <- length(t) - (rowSums(temp)-1)
y[y>length(t)] <- NA
#[1] 9 37 58 NA
fun <- function(x){
which(t > x)[1]
}
R > sapply(x, fun)
[1] 9 37 58 NA
Almost the same:
require(functional)
apply(matrix(t > rep(x, each=length(t)), length(t)), 2, Compose(which, Curry(append, Inf), min))
## [1] 9 37 58 Inf