JPV
JPV

Reputation: 1079

Apply() function to a data frame

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

Answers (3)

eddi
eddi

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

Arun
Arun

Reputation: 118779

You can create a matrix directly and just multiply the data with it:

as.matrix(trans_temp) * col(trans_temp)

Benchmarking with eddi's

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

Simon O&#39;Hanlon
Simon O&#39;Hanlon

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

Related Questions