tags:

views:

82

answers:

3

How can I get the output as a vector in R?

For example, if I want to have

for (i in 1:1000) {if i mod 123345 = 0, a = list(i)}
a

but I would want to find all i that divide evenly into 123345 (i.e., factors), and not just the largest one.

+8  A: 

There may be a more concise way to do this, but I would do it this way:

i <- 1:1000
j <- i[12345 %% i == 0 ]

The resulting vector j contains a vector of the values in i which are factors of 12345. In R the modulo operator is %% and it's a bit of a bitch to find when searching on your own. It's buried in the help document for arithmetic operators and you can find it by searching for + which must be in quotes like: ?"+" and then you have to read down a bit.

You better add a VBA tag if you want to find a VBA answer. But I suspect it will involve the VBA modulo operator ;)

JD Long
ah, nice -- thanks
A: 

You wrote:

for (i in 1:1000) {if i mod 123345 = 0, a = list(i)} a

JD Long's code is much better, but if you wanted this loopy strategy to work try instead:

a <- vector(mode="list"); for (i in 1:1000) {if (123345 %% i == 0){ a <-c(a,i) } }
as.vector(unlist(a))
+2  A: 

JD Long's method is really the first that came to mind, but another:

Filter(function(x) !(12345 %% x), 1:1000)

I think it's kind of fun to avoid any need for an explicit assignment. (Kind of too bad to create a new function each time.) (In this case, "!" converts a non-zero value to FALSE and zero to TRUE. "Filter" picks out each element evaluating to TRUE.)

Also avoiding the need for a separate allocation and not creating a new function:

which(!(12345 %% 1:1000))

Timing:

> y <- 1:1000
> system.time(replicate(1e5, y[12345 %% y == 0 ]))
   user  system elapsed 
  8.486   0.058   8.589
> system.time(replicate(1e5, Filter(function(x) !(12345 %% x), y)))

Timing stopped at: 90.691 0.798 96.118  # I got impatient and killed it
# Even pulling the definition of the predicate outside,
# it's still too slow for me want to wait for it to finish.
# I'm surprised Filter is so slow.
> system.time(replicate(1e5, which(!12345 %% y)))
   user  system elapsed 
 11.618   0.095  11.792

So, looks like JD Long's method is the winner.

David F
On my machine I got different timing, JD method~12.5s vs your method~11.5s. I'm using R-2.11.1.
Marek
Strange; on my laptop and R-2.11.1 JD -- 12.92s, David -- 5.49s, but for 1000 repetitions.
mbq
If you want real speed up try to convert everything to `integer`: `system.time(replicate(1e5, y[12345L %% y == 0L ]))`. (`0L` means `as.integer(0)`)
Marek