Reputation: 1079
I have a data frame object which has 24 columns and each one has a different length. I would like to multiply every column by a vector of 24 values. I am thinking about using the apply function since I do not have any matrix. my guess is like:
trans_temp:
Ta.f Ta.f Ta.f Ta.f
1995-10-13 04:00:00 13.6 13.6 13.6 13.6
1995-10-13 05:00:00 13.6 13.6 13.6 13.6
1995-10-13 06:00:00 13.6 13.6 13.6 13.6
1995-10-13 07:00:00 13.5 13.5 13.5 13.5
1995-10-13 08:00:00 13.5 13.5 13.5 13.5
and my vector is
x <- c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24)
So I want the first column multiplied by 1, the second by 2, the third by 3 and so on. I can not multiply directlly because it is a data.frame object.
apply(trans_temp,x,MARGIN=2,fun)
Any help?
Upvotes: 0
Views: 316
Reputation: 49448
Here's another approach without using apply
, that relies on R recycling behavior:
t(x*t(trans_temp))
This will probably be much faster than the other two approaches.
^^^ Not anymore after Arun's edits :) What this has going for it now is that you can have an arbitrary x
(and if you want an arbitrary operation in addition to arbitrary x
, then you'd go with Simon's answer).
Upvotes: 2
Reputation: 118779
You can create a matrix directly and just multiply the data with it:
as.matrix(trans_temp) * col(trans_temp)
m <- as.data.frame(matrix(runif(1e7), ncol=1000))
x <- seq_len(1000)
system.time(tt1 <- as.matrix(m) * col(m)) # 0.335 seconds
system.time(tt2 <- t(x*t(m))) # 0.505 seconds
identical(tt1, tt2) # TRUE
Upvotes: 3
Reputation: 59970
You are on the right track, but I don't understand how your columns have different lengths, unless you mean some contain, e.g. NA in them. Use MARGIN = 1
to apply across rows.
x <- c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24)
t( apply(trans_temp , MARGIN = 1 , function(y) x * y ) )
You could even shorten the call like so:
t( apply(trans_temp , 1 , `*` , x ) )
Upvotes: 2