Output vector of loop function r - r

i´m trying to create an output vector of a loop, containing a result from each loop.
out=NULL
for (i in 1:5) {
out<-cbind(out,sample(1:100, 1)) #placeholderfunction
for (i in 1:5) {out[i]<- i+1}
}
The good side: My result contains the correct values. The bad side: it does as a matrix and i don´t know why.
> out
out
[1,] 2 71 14 46 96
[2,] 3 71 14 46 96
[3,] 4 71 14 46 96
[4,] 5 71 14 46 96
[5,] 6 71 14 46 96
What i want would be something like:
> out
out
[1,] 2 71 14 46 96
Probably it is just a small step from where i stand, but i just can´t figure it out, maybe someone could help?
(and yes i could just remove but i would like my code clean)
Thanks!
Ok,
by looking at the problem again on this scale i found it - a superfluous line:
> out=NULL
> for (i in 1:5) {
+ out<-cbind(out,sample(1:100, 1))
+ }
> out
[,1] [,2] [,3] [,4] [,5]
[1,] 63 98 78 43 19

What about this
out <- sample(100,5)
Update
I see why I got a -1, the OP wants to construct a vector with a for loop. As a word of caution, creating a vector in this manner is usually not a good idea. For example, my above code is both simpler and faster than the OP's code. That withstanding, if you want generate a vector of random numbers with a for loop use this approach
my.loop <- function(l){
out_1 <- numeric(l)
for (i in 1:l) {
out_1[i] <- sample(1:100, 1)
}
out_1
}
This will be much better than op approach below because we are preallocating memory.
op.loop <- function(l){
out_2 = NULL
for (i in 1:l) {
out_2 <- cbind(out_2, sample(1:100, 1))
}
out_2
}
For fun I timed the two approaches:

Related

The first row is missing from head() function in R

Something interesting(strange) occured to me when I was trying to pull some data from the etf_env object from the rutils package.
First of all I created a variable called 'foo'.
foo <- as.list(rutils::etf_env)["VTI"]
Then I tried to call the head() function and here is the result.
> head(foo$VTI, n = 6)
VTI.Open VTI.High VTI.Low VTI.Close VTI.Volume VTI.Adjusted
2001-06-01 41.89521 42.18640 41.64041 42.0772 2542200 42.0772
2001-06-04 42.25920 42.29560 41.96801 42.2592 1018200 42.2592
2001-06-05 42.36841 42.95080 42.36841 42.8780 562400 42.8780
2001-06-06 42.76879 42.87799 42.47760 42.5140 278500 42.5140
2001-06-07 42.47761 42.73240 42.36841 42.7324 236700 42.7324
The first row is missing!
Then I created a random matrix called 'mat' and I tried to call the head() function again.
> mat <- matrix(1:100,ncol = 5)
> head(mat, n = 6)
[,1] [,2] [,3] [,4] [,5]
[1,] 1 21 41 61 81
[2,] 2 22 42 62 82
[3,] 3 23 43 63 83
[4,] 4 24 44 64 84
[5,] 5 25 45 65 85
[6,] 6 26 46 66 86
The head() function seems working just fine. How and why did this happen? I'm really scratching my head right now. Hope somebody knows the answer. Many thanks!

R Calculate big NOR matrix

I have a big square matrix in R:
norMat <- matrix(NA, nrow=1024, ncol=1024)
This empty matrix needs to be filled with the sum of all equal bits of all matrix index pairs.
So I need to calculate the logical NOR for i(rowIndex) and j(colIndex) and sum the result,e.g:
sum(intToBits(2)==intToBits(3))
Currenty, I have this function which fills the matrix:
norMatrix <- function()
{
matDim=1024
norMat <<- matrix(NA, nrow=matDim, ncol=matDim)
for(i in 0:(matDim-1)) {
for(j in 0:(matDim-1)) {
norMat[i+1,j+1] = norsum(i,j)
}
}
return(norMat)
}
And here's the norsum function:
norsum <- function(bucket1, bucket2)
{
res = sum(intToBits(bucket1)==intToBits(bucket2))
return(res)
}
Is this an efficient solution to fill the matrix?
I'm in doubt since on my machine this takes over 5 minutes.
I suggest this is a great opportunity for the *apply functions. Here's one solution that's a bit faster than 5 minutes.
First, proof of concept, non-square solely for clarity of dimensions.
nc <- 5
nr <- 6
mtxi <- sapply(seq_len(nc), intToBits)
mtxj <- sapply(seq_len(nr), intToBits)
sapply(1:nc, function(i) sapply(1:nr, function(j) sum(mtxi[,i] == mtxj[,j])))
# [,1] [,2] [,3] [,4] [,5]
# [1,] 32 30 31 30 31
# [2,] 30 32 31 30 29
# [3,] 31 31 32 29 30
# [4,] 30 30 29 32 31
# [5,] 31 29 30 31 32
# [6,] 29 31 30 31 30
Assuming that these are correct, the full meal deal:
n <- 1024
mtx <- sapply(seq_len(n), intToBits)
system.time(
ret <- sapply(1:n, function(i) sapply(1:n, function(j) sum(mtx[,i] == mtx[,j])))
)
# user system elapsed
# 3.25 0.00 3.36
You don't technically need to pre-calculate mtxi and mtxj. Though intToBits does not introduce much overhead, I think it's silly to recalculate every time.
My system is reasonable (i7 6600U CPU # 2.60GHz), win10_64, R-3.3.2 ... nothing too fancy.

Loop over matrix using n consecutive rows in R

I have a matrix that consists of two columns and a number (n) of rows, while each row represents a point with the coordinates x and y (the two columns).
This is what it looks (LINK):
V1 V2
146 17
151 19
153 24
156 30
158 36
163 39
168 42
173 44
...
now, I would like to use a subset of three consecutive points starting from 1 to do some fitting, save the values from this fit in another list, an den go on to the next 3 points, and the next three, ... till the list is finished. Something like this:
Data_Fit_Kasa_1 <- CircleFitByKasa(Data[1:3,])
Data_Fit_Kasa_2 <- CircleFitByKasa(Data[3:6,])
....
Data_Fit_Kasa_n <- CircleFitByKasa(Data[i:i+2,])
I have tried to construct a loop, but I can't make it work. R either tells me that there's an "unexpected '}' in "}" " or that the "subscript is out of bonds". This is what I've tried:
minimal runnable code
install.packages("conicfit")
library(conicfit)
CFKasa <- NULL
Data.Fit <- NULL
for (i in 1:length(Data)) {
row <- Data[i:(i+2),]
CFKasa <- CircleFitByKasa(row)
Data.Fit[i] <- CFKasa[3]
}
RStudio Version 0.99.902 – © 2009-2016 RStudio, Inc.; Win10 Edu.
The third element of the fitted circle (CFKasa[3]) represents the radius, which is what I am really interested in. I am really stuck here, please help.
Many thanks in advance!
Best, David
Turn your data into a 3D array and use apply:
DF <- read.table(text = "V1 V2
146 17
151 19
153 24
156 30
158 36
163 39", header = TRUE)
a <- t(DF)
dim(a) <-c(nrow(a), 3, ncol(a) / 3)
a <- aperm(a, c(2, 1, 3))
# , , 1
#
# [,1] [,2]
# [1,] 146 17
# [2,] 151 19
# [3,] 153 24
#
# , , 2
#
# [,1] [,2]
# [1,] 156 30
# [2,] 158 36
# [3,] 163 39
center <- function(m) c(mean(m[,1]), mean(m[,2]))
t(apply(a, 3, center))
# [,1] [,2]
#[1,] 150 20
#[2,] 159 35
center(DF[1:3,])
#[1] 150 20

R - Apply function with different argument value for each row/column of a matrix

I am trying to apply a function to each row or column of a matrix, but I need to pass a different argument value for each row.
I thought I was familiar with lapply, mapply etc... But probably not enough.
As a simple example :
> a<-matrix(1:100,ncol=10);
> a
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1 11 21 31 41 51 61 71 81 91
[2,] 2 12 22 32 42 52 62 72 82 92
[3,] 3 13 23 33 43 53 63 73 83 93
[4,] 4 14 24 34 44 54 64 74 84 94
[5,] 5 15 25 35 45 55 65 75 85 95
[6,] 6 16 26 36 46 56 66 76 86 96
[7,] 7 17 27 37 47 57 67 77 87 97
[8,] 8 18 28 38 48 58 68 78 88 98
[9,] 9 19 29 39 49 59 69 79 89 99
[10,] 10 20 30 40 50 60 70 80 90 100
Let's say I want to apply a function to each row, I would do :
apply(a, 1, myFunction);
However my function takes an argument, so :
apply(a, 1, myFunction, myArgument);
But if I want my argument to take a different value for each row, I cannot find the right way to do it.
If I define a 'myArgument' with multiple values, the whole vector will obviously be passed to each call of 'myFunction'.
I think that I would need a kind of hybrid between apply and the multivariate mapply. Does it make sense ?
One 'dirty' way to achieve my goal is to split the matrix by rows (or columns), use mapply on the resulting list and merge the result back to a matrix :
do.call(rbind, Map(myFunction, split(a,row(a)), as.list(myArgument)));
I had a look at sweep, aggregate, all the *apply variations but I wouldn't find the perfect match to my need. Did I miss it ?
Thank you for your help.
You can use sweep to do that.
a <- matrix(rnorm(100),10)
rmeans <- rowMeans(a)
a_new <- sweep(a,1,rmeans,`-`)
rowMeans(a_new)
I don't think there are any great answers, but you can somewhat simplify your solution by using mapply, which handles the "rbind" part for you, assuming your function always returns the same sizes vector (also, Map is really just mapply):
a <- matrix(1:80,ncol=8)
myFun <- function(x, y) (x - mean(x)) * y
myArg <- 1:nrow(a)
t(mapply(myFun, split(a, row(a)), myArg))
I know the topic is quiet old but I had the same issue and I solved it that way:
# Original matrix
a <- matrix(runif(n=100), ncol=5)
# Different value for each row
v <- runif(n=nrow(a))
# Result matrix -> Add a column with the row number
o <- cbind(1:nrow(a), a)
fun <- function(x, v) {
idx <- 2:length(x)
i <- x[1]
r <- x[idx] / v[i]
return(r)
}
o <- t(apply(o, 1, fun, v=v)
By adding a column with the row number to the left of the original matrix, the index of the needed value from the argument vector can be received from the first column of the data matrix.

How to write function that takes uses the single ouput from another function as starting point for new analysis?

I'm having trouble writing a function that calls another function and uses the output as the basis for running new analysis in a loop (or equivalent). For example, let's say function 1 creates this output: 10. The second function would take that as a starting point to run new analysis. The single data point from the second output would then be the basis for the next round of analysis, and so on.
Here's a simple example. The question is how to create a for loop for this. Or perhaps there's a more efficient way using lapply. In any case, the first function might be as follows:
f.1 <-function(x) {
x
a <-seq(x,by=1,length.out=5)
a.1 <-tail(a,1)
}
The second function, which calls the first function, could run as follows:
f.2 <-function(x) {
f.1 <-function(x) {
a <-seq(x,by=1,length.out=5)
a.1 <-tail(a,1)
}
z <-f.1(x)
y=z+1
seq(y,by=1,length.out=5)
}
How can I modify f.2() so that it re-runs that computation using the previous output as the basis for the next round of analysis. To be precise, f.1(10) outputs:
[1] 14
In turn, f.2(10) results in:
[1] 15 16 17 18 19
How can I re-write f.2() so that it automatically computes f.2(19) on the next iteration, and continually do so for several loops. In the process, I'd like to collect the outputs in a separate file for review. Thanks much!
The magrittr library (which is used most notably by dplyr) makes this type of chaining somewhat simple. First, define the functions,
f.1 <-function(x) {
x
a <- seq(x, by=1, length.out=5)
a.1 <- tail(a,1)
}
f.2 <-function(x) {
y <- x+1
seq(y, by=1, length.out=5)
}
then
library(magrittr)
f.1(10) %>% f.2
# [1] 15 16 17 18 19
As #BondedDust mentioned, you could use Reduce although normally it expects to use the same function over and over so you just need to flip the most common use case
Reduce(function(x,f) f(x), list(f.1, f.2), init=10)
# [1] 15 16 17 18 19
You can try this with two arguments for f.2. The first argument is the x value that you need to initialize x with and n is the number of iterations that you want to do. The output of the function will be a matrix containing n rows and 5 columns.
f.2 <-function(x, n) {
c <- matrix(nrow=n, ncol=5)
for (i in 1:nrow(c))
{
z <-f.1(x) ##if you have already defined your f.1(x) beforehand, there is no need to define it again in f.2. you can simply use z <- f.1(x) like it is done here
y=z+1
c[i,] = seq(y, by=1, length.out=5)
x = c[i,5]
}
return(c)
}
The output of
f <- f.2(10, 10) ##initialising x with 10 and running 10 loops
f
[,1] [,2] [,3] [,4] [,5]
[1,] 15 16 17 18 19
[2,] 24 25 26 27 28
[3,] 33 34 35 36 37
[4,] 42 43 44 45 46
[5,] 51 52 53 54 55
[6,] 60 61 62 63 64
[7,] 69 70 71 72 73
[8,] 78 79 80 81 82
[9,] 87 88 89 90 91
[10,] 96 97 98 99 100

Resources