I have this mathematical function
I have written R code:
result <- 0
for (i in length(v)) {
result <- abs(x-v[i])
}
return(result)
to compute the function.
However, this does not seems efficient to me? How to implement this sum with the R sum() function?
I appreciate your answer!
sum(abs(x-v)) show be enough, no need the for loop, since arithmetic operations in R are vectorized
# Example
> x <- 5
> v <- 1:10
> abs(x-v)
[1] 4 3 2 1 0 1 2 3 4 5
> sum(abs(x-v))
[1] 25
Related
I am attempting to create a loop that runs a function with specific values of i in a vector:
For example I would like to save i + 2 for when i is 1 and 5
test<- c()
for(i in c(1,5)){
test[i] <- i + 2
}
This ends up printing NA for 2 ,3 and 4:
[1] 3 NA NA NA 7
while the result I would like is:
[1] 3 7
This is probably very elementary but I cannot seem to figure this out.
R is vectorized, means you can do this:
c(1, 5) + 2
# [1] 3 7
for loops in R are often very slow, which is why they are implemented in C in functions of the *apply family, e.g.
sapply(c(1, 5), \(i) i + 2)
# [1] 3 7
If you really need to rely on a for loop, If you really need to rely on a "for" loop, you may want to loop over the indices rather than the values (a quite common mistake!):
v <- c(1, 5)
test <- vector('numeric', length(v))
for (i in seq_along(v)) {
test[i] <- v[i] + 2
}
test
# [1] 3 7
Use append
test<- c()
for(i in c(1,5)){
test<-append(test,i+2)
}
I am trying to make function that prints values of Fibonacci sequence that are under user given value (n). So input 8 will return values (1,1,2,3,5,8)
Fib<- function(n){
v=NULL
v[1]<-1
v[2]<-1
for(i in 3:n){
v[i]<-v[i-1]+v[i-2]
while(v[i]<=n){
print(v)
break}}}
input
fib(8)
[1] 1 1 2
[1] 1 1 2 3
[1] 1 1 2 3 5
[1] 1 1 2 3 5 8
I would want only the last one printed out.
I also tried it with append(v,v[i]) but haven't got that working so it would return only values below n.
Will appreciate any tips given.
You can try a recursive approach (if you want, you can modify this to let the limit be an input, but I like it better this way to conserve stack space ):
V = c(1,1)
Limit = 10
fib = function(n){
if(n > L){
print(V)
return()
}else{
n = V[(length(V)-1) : length(V)] %>% sum
V <<- c(V,n)
return(fib(n))
}
}
fib(0)
You can use one only while without break to reach it:
Fib<- function(n){
v=NULL
v[1]<-1
v[2]<-1
i<-2
while(v[i]<=n)
{
i<-i+1
v[i]<-as.numeric(v[i-1])+as.numeric(v[i-2])
}
print(v[1:length(v)-1])
}
This is your desired output:
Fib(8)
[1] 1 1 2 3 5 8
m <- matrix(1:4, ncol=2)
l <- list(a=1:3, b='c')
d <- data.frame(a=1:3, b=3:1)
I was wondering if it is possible to make a function that takes a base R object (matrix, vector, list or data.frame, ...) as well as a text that specifies the subset of the object.
f1 <- function(object, subset) {
# object'subset'
}
For instance
f1(m, '[1,1]') #to evaluate m[1,1]
f1(l, '[[1]][2:3]') #l[[1]][2:3]
f1(d, '$a') #d$a
would give us (respectively):
[1] 1
[1] 2 3
[1] 1 2 3
I guess the function need somehow to glue the two arguments before evaluating. I guess one could make a kind of interpreter for each bit of the subset text and the (for the matrix example) do something like:
`[`(1,1)
This would possible but I thought there would be an easier more direct way (my 'glue' above).
Well one way to go is to use eval(parse)) methodology, i.e.
f1 <- function(x, text){
eval(parse(text = paste0(x, text)))
}
f1('d', '$a')
#[1] 1 2 3
f1('m', '[1,1]')
#[1] 1
f1('l', '[[1]][2:3]')
#[1] 2 3
f1<-function(object, subset){
return(eval(parse(text=paste0(substitute(object),subset))))
}
> m=matrix(4,2,2)
> l=list(c(1,2,3),c(2,3,4))
> f1(m,'[1,1]')
[1] 4
> f1(l,'[[1]][1:2]')
[1] 1 2
I pass a data.frame as parameter to a function that want to alter the data inside:
x <- data.frame(value=c(1,2,3,4))
f <- function(d){
for(i in 1:nrow(d)) {
if(d$value[i] %% 2 == 0){
d$value[i] <-0
}
}
print(d)
}
When I execute f(x) I can see how the data.frame inside gets modified:
> f(x)
value
1 1
2 0
3 3
4 0
However, the original data.frame I passed is unmodified:
> x
value
1 1
2 2
3 3
4 4
Usually I have overcame this by returning the modified one:
f <- function(d){
for(i in 1:nrow(d)) {
if(d$value[i] %% 2 == 0){
d$value[i] <-0
}
}
d
}
And then call the method reassigning the content:
> x <- f(x)
> x
value
1 1
2 0
3 3
4 0
However, I wonder what is the effect of this behaviour in a very large data.frame, is a new one grown for the method execution? Which is the R-ish way of doing this?
Is there a way to modify the original one without creating another one in memory?
Actually in R (almost) each modification is performed on a copy of the previous data (copy-on-writing behavior).
So for example inside your function, when you do d$value[i] <-0 actually some copies are created. You usually won't notice that since it's well optimized, but you can trace it by using tracemem function.
That being said, if your data.frame is not really big you can stick with your function returning the modified object, since it's just one more copy afterall.
But, if your dataset is really big and doing a copy everytime can be really expensive, you can use data.table, that allows in-place modifications, e.g. :
library(data.table)
d <- data.table(value=c(1,2,3,4))
f <- function(d){
for(i in 1:nrow(d)) {
if(d$value[i] %% 2 == 0){
set(d,i,1L,0) # special function of data.table (see also ?`:=` )
}
}
print(d)
}
f(d)
print(d)
# results :
> f(d)
value
1: 1
2: 0
3: 3
4: 0
>
> print(d)
value
1: 1
2: 0
3: 3
4: 0
N.B.
In this specific case, the loop can be replaced with a "vectorized" and more efficient version e.g. :
d[d$value %% 2 == 0,'value'] <- 0
but maybe your real loop code is much more convoluted and cannot be vectorized easily.
I'm looking for a function that
can list all n! permutations of a given input vector (typically just the sequence 1:n)
can also list just the first N of all n! permutations
The first requirement is met, e.g., by permn() from package combinat, permutations() from package e1071, or permutations() from package gtools. However, I'm positive that there is yet another function from some package that also provides the second feature. I used it once, but have since forgotten its name.
Edit:
The definition of "first N" is arbitrary: the function just needs an internal enumeration scheme which is always followed, and should break after N permutations are computed.
As Spacedman correctly pointed out, it's crucial that the function does not compute more permutations than actually needed (to save time).
Edit - solution: I remembered what I was using, it was numperm() from package sna. numperm(4, 7) gives the 7th permutation of elements 1:4, for the first N, one has to loop.
It seems like the best way to approach this would be to construct an iterator that could produce the list of permutations rather than using a function like permn which generates the entire list up front (an expensive operation).
An excellent place to look for guidance on constructing such objects is the itertools module in the Python standard library. Itertools has been partially re-implemented for R as a package of the same name.
The following is an example that uses R's itertools to implement a port of the Python generator that creates iterators for permutations:
require(itertools)
permutations <- function(iterable) {
# Returns permutations of iterable. Based on code given in the documentation
# of the `permutation` function in the Python itertools module:
# http://docs.python.org/library/itertools.html#itertools.permutations
n <- length(iterable)
indicies <- seq(n)
cycles <- rev(indicies)
stop_iteration <- FALSE
nextEl <- function(){
if (stop_iteration){ stop('StopIteration', call. = FALSE) }
if (cycles[1] == 1){ stop_iteration <<- TRUE } # Triggered on last iteration
for (i in rev(seq(n))) {
cycles[i] <<- cycles[i] - 1
if ( cycles[i] == 0 ){
if (i < n){
indicies[i:n] <<- c(indicies[(i+1):n], indicies[i])
}
cycles[i] <<- n - i + 1
}else{
j <- cycles[i]
indicies[c(i, n-j+1)] <<- c(indicies[n-j+1], indicies[i])
return( iterable[indicies] )
}
}
}
# chain is used to return a copy of the original sequence
# before returning permutations.
return( chain(list(iterable), new_iterator(nextElem = nextEl)) )
}
To misquote Knuth: "Beware of bugs in the above code; I have only tried it, not proved it correct."
For the first 3 permutations of the sequence 1:10, permn pays a heavy price for computing unnecessary permutations:
> system.time( first_three <- permn(1:10)[1:3] )
user system elapsed
134.809 0.439 135.251
> first_three
[[1]]
[1] 1 2 3 4 5 6 7 8 9 10
[[2]]
[1] 1 2 3 4 5 6 7 8 10 9
[[3]]
[1] 1 2 3 4 5 6 7 10 8 9)
However, the iterator returned by permutations can be queried for only the first three elements which spares a lot of computations:
> system.time( first_three <- as.list(ilimit(permutations(1:10), 3)) )
user system elapsed
0.002 0.000 0.002
> first_three
[[1]]
[1] 1 2 3 4 5 6 7 8 9 10
[[2]]
[1] 1 2 3 4 5 6 7 8 10 9
[[3]]
[1] 1 2 3 4 5 6 7 9 8 10
The Python algorithm does generate permutations in a different order than permn.
Computing all the permutations is still possible:
> system.time( all_perms <- as.list(permutations(1:10)) )
user system elapsed
498.601 0.672 499.284
Though much more expensive as the Python algorithm makes heavy use of loops compared to permn. Python actually implements this algorithm in C which compensates for the inefficiency of interpreted loops.
The code is available in a gist on GitHub. If anyone has a better idea, fork away!
In my version of R/combinat, the function permn() is just over thirty lines long. One way would be to make a copy of permn and change it to stop early.