NeoXx
NeoXx

Reputation: 113

R: Writing a function which has as its input a vector

I started learning R recently and don't know how to write this:

Write a function which has as its input a vector where each element is a positive integer below 500 000 000, and which returns each element of the input vector which is a cube number.

When I got a single value x, I usually start with:

my.function <- function(x) {

However what if I want a vector as outlined above? I was thinking of defining x as below:

my.function <- function(x) { 
x <- c(0<n<500000000)

but this does not work. How can I do this?

Upvotes: 0

Views: 14035

Answers (2)

SamPassmore
SamPassmore

Reputation: 1365

You do not need to do anything differently in terms of creating the function as @Adam correctly states.

my_function = function(x){} 

is all you need.

You can check whether the input fits your constraints after this point. For example:

my_function = function(x){
    if(!is.vector(x))
        stop("Not a vector")

    if(any(x < 0 | x > 500000))
        stop("Does not fit constraints")
}

Upvotes: 3

IRTFM
IRTFM

Reputation: 263301

Perhaps:

 x [ mapply( function(xx,yy) {isTRUE(all.equal(xx,yy))}, 
                 xx=(x) ^ (1/3) , 
                 yy=round(  (x) ^ (1/3), 0 ) ) ]

> x <- 1:512  # to get your desired range it would be `seq.int(500000000)`
> x[ mapply( function(xx,yy) {isTRUE(all.equal(xx,yy))}, 
                xx=(x) ^ (1/3) , 
                yy=round(  (x) ^ (1/3), 0 ) ) ]
[1]   1   8  27  64 125 216 343 512

I think that 500 000 000 is below integer.max or max.integer. You should check .Machine

(This is going to be slow. Better algorithms are possible and perhaps that is perhaps what your instructor wants.)

> x <- seq.int(50000)
> cubes
 [1]    1    8   27   64  125  216  343  512  729 1000 1331 1728 2197 2744 3375
[16] 4096 4913
> cubes <- x[ mapply( function(xx,yy) {isTRUE(all.equal(xx,yy))}, xx=(x) ^ (1/3) , yy=round(  (x) ^ (1/3), 0 ) ) ]
> cubes
 [1]     1     8    27    64   125   216   343   512   729  1000  1331  1728
[13]  2197  2744  3375  4096  4913  5832  6859  8000  9261 10648 12167 13824
[25] 15625 17576 19683 21952 24389 27000 29791 32768 35937 39304 42875 46656

I suspect this is linear in length of x

> x <- seq.int(500000)
> system.time( {cubes <- x[ mapply( function(xx,yy) {isTRUE(all.equal(xx,yy))}, xx=(x) ^ (1/3) , yy=round(  (x) ^ (1/3), 0 ) ) ] } )
   user  system elapsed 
105.455   1.110 107.138 

This only require checking a relatively few values, since cube-root of your max is only 793 plus a fraction:

x[ x %in% (1:(max(x)^(1/3)) )^3]   # almost instantaneous with x <- 1:500000
#   ==== testing worst case scenario ====
> x <- 1:500000000
> system.time( {cubes <- x[ x %in% (1:(max(x)^(1/3)) )^3]})
   user  system elapsed 
 25.025   8.379  32.857   # that's in seconds

Upvotes: 1

Related Questions