Vasile
Vasile

Reputation: 1017

How to make a function skip an argument from a vector

Say I have the following function

power<-function (number){
   number^2
  }

I also have a vector -z

z<- c(1:3, "a", 7:9)

I would like to apply the power function over the vector variables. If everything is a number, the functions works well using this code, which creates a list as I want:

q<-lapply(z, FUN=power)

How do I make the function skip, if it does not find a valid argument? In this case skip "a". Let's say removing the odd argument is not an option for my task. I might also have cases when the function does not find the argument at all (e.g. empty space, missing tag on a web page). Would be nice if the solution could work for these instances as well. Thanks.

Upvotes: 3

Views: 265

Answers (4)

ThomasIsCoding
ThomasIsCoding

Reputation: 101335

Try the code below

power <- Vectorize(function(number) {
    ifelse(is.numeric(number), number^2, number)
})
z <- list(1:3, "a", 7:9)
lapply(z, power)

which gives

> lapply(z, power)
[[1]]
[1] 1 4 9

[[2]]
  a
"a"

[[3]]
[1] 49 64 81

Upvotes: 1

Anoushiravan R
Anoushiravan R

Reputation: 21908

We can also write a custom function that wraps power inside lapply. Basically an equivalent of map_if:

z <- list(1:3, "a", 7:9)

lapply(z, function(x) {
  if(all(is.numeric(x))) {
    power(x)
  } else {
    x
  }
})

[[1]]
[1] 1 4 9

[[2]]
[1] "a"

[[3]]
[1] 49 64 81

Upvotes: 3

Bill O&#39;Brien
Bill O&#39;Brien

Reputation: 872

This will try to coerce the elements of the supplied vector to numeric. Values not coercible will have NA returned. Note that your input vector z may not be what you intended, i.e. it resolves to a character vector c("1", "2", "3", "a", ...) and not c(1, 2, 3, "a", 7, 8, 9).

power<-function (number){
  result<- as.numeric(number)^2
  }

z <- c(1:3, "a", 7:9)

lapply(z, power)


 [[1]]
[1] 1

[[2]]
[1] 4

[[3]]
[1] 9

[[4]]
[1] NA

[[5]]
[1] 49

[[6]]
[1] 64

[[7]]
[1] 81

Upvotes: 4

akrun
akrun

Reputation: 887108

Consider creating a list instead of a vector as list can have multiple types whereas vector can have only a single class and if there is a single character element, it returns the whole object as character

z <- list(1:3, "a", 7:9)
lapply(Filter(is.numeric, z), FUN = power)

Or with map_if

library(purrr)
map_if(z, .p = is.numeric, .f = power)

-output

[[1]]
[1] 1 4 9

[[2]]
[1] "a"

[[3]]
[1] 49 64 81

Upvotes: 4

Related Questions