user10072460
user10072460

Reputation:

Calculating data and generating rows in R

I want to calculate row with columns using the following function: row * EXP(columns)

Here is the data:

df<-read.table(text=" Time
2.5
2.1
2.2
3.1
4
-2
-3
-1",h=T)



df2= c(0.2, -0.1,   1,  2)

For example, 2.5*EXp(0.2); 2.5*EXP (-0.1), 2.5 *EXP(1), 2.5*EXP(2) The same for 2.1,2.2,.....-3.0.

This gives me the following table:

0.2 -0.1    1   2
3.053506895 9.603172812 893.9989236 18.47264025
2.564945792 6.686954761 301.3860014 15.51701781
2.687086068 7.320234183 395.5273835 16.25592342
3.78634855  16.52700973 4567.282501 22.90607391
4.885611033 37.31329406 52739.88682 29.5562244
-2.442805516    0.16370736  0.004354421 -14.7781122
-3.664208274    0.066237252 0.00028734  -22.1671683
-1.221402758    0.404607662 0.065988036 -7.389056099

I can do it based on Excel =(A3*EXP($D$2)), but I struggle to do it using R. Any help will be appreciated.

Upvotes: 0

Views: 68

Answers (3)

denis
denis

Reputation: 5673

You can do this:

t(sapply(df$Time, function(e){e*exp(df2)}))

          [,1]       [,2]      [,3]       [,4]
[1,]  3.053507  2.2620935  6.795705  18.472640
[2,]  2.564946  1.9001586  5.708392  15.517018
[3,]  2.687086  1.9906423  5.980220  16.255923
[4,]  3.786349  2.8049960  8.426674  22.906074
[5,]  4.885611  3.6193497 10.873127  29.556224
[6,] -2.442806 -1.8096748 -5.436564 -14.778112
[7,] -3.664208 -2.7145123 -8.154845 -22.167168
[8,] -1.221403 -0.9048374 -2.718282  -7.389056

or:

Reduce(rbind,lapply(df$Time, function(e){e*exp(df2)}))

          [,1]       [,2]      [,3]       [,4]
init  3.053507  2.2620935  6.795705  18.472640
      2.564946  1.9001586  5.708392  15.517018
      2.687086  1.9906423  5.980220  16.255923
      3.786349  2.8049960  8.426674  22.906074
      4.885611  3.6193497 10.873127  29.556224
     -2.442806 -1.8096748 -5.436564 -14.778112
     -3.664208 -2.7145123 -8.154845 -22.167168
     -1.221403 -0.9048374 -2.718282  -7.389056

The exp function is vectorized:

exp(df2)
[1] 1.2214028 0.9048374 2.7182818 7.3890561

So the idea is to loop over the factor vector in front of your exponential, and to concatenate the output. You could do it old style with for loop and an empty table that you fill also. Here is what I proposed:

lapply is a loop which output a list :

lapply(df$Time, function(e){e*exp(df2)})
[[1]]
[1]  3.053507  2.262094  6.795705 18.472640

[[2]]
[1]  2.564946  1.900159  5.708392 15.517018

[[3]]
[1]  2.687086  1.990642  5.980220 16.255923

[[4]]
[1]  3.786349  2.804996  8.426674 22.906074

[[5]]
[1]  4.885611  3.619350 10.873127 29.556224

[[6]]
[1]  -2.442806  -1.809675  -5.436564 -14.778112

[[7]]
[1]  -3.664208  -2.714512  -8.154845 -22.167168

[[8]]
[1] -1.2214028 -0.9048374 -2.7182818 -7.3890561

To concatenate, you want to bind the rows together (with rbind) on all the list, and that is what Reduce do: apply a function on the list.

sapply is a version of lapply which attempt to give a nice output, but it was in the wrong sense, so I had to transpose it with t().

Upvotes: 1

Cole
Cole

Reputation: 11255

You should also look at outer(). It's exactly what you want for this solution:

outer(df$Time, exp(df2))

          [,1]       [,2]      [,3]       [,4]
[1,]  3.053507  2.2620935  6.795705  18.472640
[2,]  2.564946  1.9001586  5.708392  15.517018
[3,]  2.687086  1.9906423  5.980220  16.255923
[4,]  3.786349  2.8049960  8.426674  22.906074
[5,]  4.885611  3.6193497 10.873127  29.556224
[6,] -2.442806 -1.8096748 -5.436564 -14.778112
[7,] -3.664208 -2.7145123 -8.154845 -22.167168
[8,] -1.221403 -0.9048374 -2.718282  -7.389056

Note the default function for outer is multiplication. That is outer(X, Y, FUN = '*'). You can change the function to other stuff as well like outer(X, Y, FUN = '+') or any function you want.

Upvotes: 0

Fnguyen
Fnguyen

Reputation: 1177

How many EXP-values do you have? If it is only a handful this is a simple solution using dplyr, I have added an example for the first two columns:

library(dplyr)
df %>%
  mutate("0.2" = Time*exp(0.2),"-0.1" = Time*exp(-0.1)) %>%
  head()

Here a solution in base r for the first column.

df["0.2"] <-df$Time*exp(0.2)

If you have a lot of EXP-values in your df2 you have to use a function from the apply family but with a handful this will work.

Upvotes: 0

Related Questions