Reputation:
I have written a function like this:
myfunc <- function(data, c1, c2, c3) {
res <- data*c1*c2*c3
return(res)
}
To apply myfunc
on the vector data
I could use
lapply(data, myfunc, c1=2, c2=3, c3=4)
But I have to loop through an id along with the vector data
, so that every row of the resulting vector (or matrix) contains an id and the respective result.
So for the simple case this would be:
myfunc <- function(id, data, c1, c2, c3) {
res <- data*c1*c2*c3
return(c(id, res))
}
But I cant use lapply
on that.
I already tried to put all input (id, data, c1, c2, c3
) in a matrix to use apply
:
apply(matrix, 1, myfunc)
But it did not work.
So what would be the best way to achieve this?
Thanks in advance!
EDIT:
This could be the data matrix:
id data c1 c2 c3
[1,] 32 1.12 2 2.5 2.8
[2,] 33 1.14 2 2.5 2.8
[3,] 34 1.21 2 2.5 2.8
[4,] 35 1.22 2 2.5 2.8
[5,] 36 1.27 2 2.5 2.8
[6,] 37 1.30 2 2.5 2.8
[7,] 38 1.32 2 2.5 2.8
[8,] 39 1.36 2 2.5 2.8
[9,] 40 1.44 2 2.5 2.8
[10,] 41 1.45 2 2.5 2.8
Column id shall get looped through and the myfunc shall be applied on the other columns. I expect (or demand) a result like this:
id res
[1,] 32 15.68
[2,] 33 15.96
[3,] 34 16.94
[4,] 35 17.08
[5,] 36 17.78
[6,] 37 18.20
[7,] 38 18.48
[8,] 39 19.04
[9,] 40 20.16
[10,] 41 20.30
Upvotes: 0
Views: 698
Reputation: 24545
Why not have data in a dataframe and then:
> ddf$res = with(ddf, data*c1*c2*c3)
> ddf
id data c1 c2 c3 res
[1,] 32 1.12 2 2.5 2.8 15.68
[2,] 33 1.14 2 2.5 2.8 15.96
[3,] 34 1.21 2 2.5 2.8 16.94
[4,] 35 1.22 2 2.5 2.8 17.08
[5,] 36 1.27 2 2.5 2.8 17.78
[6,] 37 1.30 2 2.5 2.8 18.20
[7,] 38 1.32 2 2.5 2.8 18.48
[8,] 39 1.36 2 2.5 2.8 19.04
[9,] 40 1.44 2 2.5 2.8 20.16
[10,] 41 1.45 2 2.5 2.8 20.30
Upvotes: 0
Reputation: 31171
No need to use a function, using data.table
here is an atomic example of your data:
library(data.table)
lst = list(id=c(32,33,34), data=c(1.12,1.14,1.21), c1=rep(2,3),c2=rep(2.5,3),c3=rep(2.8,3))
M = do.call(cbind, lst)
# id data c1 c2 c3
#[1,] 32 1.12 2 2.5 2.8
#[2,] 33 1.14 2 2.5 2.8
#[3,] 34 1.21 2 2.5 2.8
dt = as.data.table(M)
We can proceed with:
dt[,res:=data*c1*c2*c3]
as.matrix(dt[,list(id,res)])
# id res
#[1,] 32 15.68
#[2,] 33 15.96
#[3,] 34 16.94
Upvotes: 1
Reputation: 3429
I'd personally rather do it with an apply
:
x <- data.frame(id = 32:41,
data = c(1.12, 1.14, 1.21, 1.22, 1.27, 1.3, 1.32, 1.36, 1.44, 1.45),
c1 = c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L),
c2 = c(2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5),
c3 = c(2.8, 2.8, 2.8, 2.8, 2.8, 2.8, 2.8, 2.8, 2.8, 2.8))
x$res <- apply(x[,-1],1,prod)
x[, c("id", "res")]
Upvotes: 1
Reputation: 1
Unless I'm being dumb this could be quite simple.
So, you understand how to use lapply to create the vector res
, right? Just join it with your id column. They will be in the same order so the IDs will match up.
cbind(data$id, res)
Upvotes: 0