简体   繁体   中英

Apply a function that uses a column in the dataframe as input to every value on 1:n columns and rows

I am trying to apply two simple functions in two steps to all rows over the 1:n columns in a matrix or df where I want to use the value in the last column as an input in the function. This question might be a duplicate but, I simply cannot find the solution I am looking for. I have tried with writing a function, the apply and dplyr functions but get stuck every where with how to refer to specific columns and get a individual result for each combination of x, y.

I have looked at the answers here [ how to apply a function to every row of a matrix (or a data frame) in R and here:

But these operations are mostly row or column wise, and I need the function to work on every observation, ie

This is a simplified example of my data- but my data frames are of be of different length in both variables and length, as I am measuring depth profiles of variable depths.

1st desired function:

df<- matrix(c( 
      1.11543500, 1.09273900, 1.09362300, 1.09073300, 1.09668300, 0.0876387143,
      1.08729500, 1.06946100, 1.06227900, 1.06633600, 1.06690000, 0.0853604143,
      1.05458300, 1.03921000, 1.03225300, 1.03782000, 1.03416200, 0.0790749429,
      1.02783210, 1.01204520, 1.00525750, 1.00781250, 1.00666170,  0.0756004571
    ), nrow = 4, byrow = TRUE)

First I need to have the df in wide format to apply a function like;

For each row of V1:V5 subtract by V6, which would give an output like this (would be fine to to leave V6 out:

 df1
       V1         V2          V3          V4           V5          V6
1 1.027796286   1.005100286 1.005984286 1.003094286 1.009044286 0.087638714
2 1.001934586   0.984100586 0.976918586 0.980975586 0.981539586 0.085360414
3 0.975508057   0.960135057 0.953178057 0.958745057 0.955087057 0.079074943
4 0.952231643   0.936444743 0.929657043 0.932212043 0.931061243 0.075600457

I have tried:

    df1<- apply(df, 1, function(x) x[1:5]-x[6])

and it gave me this, which is wrong:

df1    [,1]      [,2]      [,3]      [,4]
 [1,] 1.027796 1.0019346 0.9755081 0.9522316
 [2,] 1.005100 0.9841006 0.9601351 0.9364447
 [3,] 1.005984 0.9769186 0.9531781 0.9296570
 [4,] 1.003094 0.9809756 0.9587451 0.9322120
 [5,] 1.009044 0.9815396 0.9550871 0.9310612

Anyone with a suggestion on how to correct the code? I am also open for suggestions in eg dplyr or functions to call.

I am hoping that it also would give me an answer on how to continue with the next step, where I would have to transpose the results from the first calculation and add some other columns with temp and salinity values as well as constants to calculate by a formula like:

  x = z- [constant_t * (t1 - t2) + constant_s * S]

where z would be the output from the first calculation.

You could use mutate_at from dplyr to do this. I've used ncol to identify which columns to use. You can then use t() as @PoGibas suggests to continue on to the next step.

library(dplyr)
df <- as_tibble(df) 
df1 <- mutate_at(df, 1:(ncol(df) -1), funs(. - df[[ncol(df)]]))
df1
#> # A tibble: 4 x 6
#>          V1        V2        V3        V4        V5         V6
#>       <dbl>     <dbl>     <dbl>     <dbl>     <dbl>      <dbl>
#> 1 1.0277963 1.0051003 1.0059843 1.0030943 1.0090443 0.08763871
#> 2 1.0019346 0.9841006 0.9769186 0.9809756 0.9815396 0.08536041
#> 3 0.9755081 0.9601351 0.9531781 0.9587451 0.9550871 0.07907494
#> 4 0.9522316 0.9364447 0.9296570 0.9322120 0.9310612 0.07560046

t(df1)
#>          [,1]       [,2]       [,3]       [,4]
#> V1 1.02779629 1.00193459 0.97550806 0.95223164
#> V2 1.00510029 0.98410059 0.96013506 0.93644474
#> V3 1.00598429 0.97691859 0.95317806 0.92965704
#> V4 1.00309429 0.98097559 0.95874506 0.93221204
#> V5 1.00904429 0.98153959 0.95508706 0.93106124
#> V6 0.08763871 0.08536041 0.07907494 0.07560046

If you prefer to drop the last variable from the result you can use transmute_at instead of mutate_at :

transmute_at(df, 1:(ncol(df) -1), funs(. - df[[ncol(df)]]))

#> # A tibble: 4 x 5
#>          V1        V2        V3        V4        V5
#>       <dbl>     <dbl>     <dbl>     <dbl>     <dbl>
#> 1 1.0277963 1.0051003 1.0059843 1.0030943 1.0090443
#> 2 1.0019346 0.9841006 0.9769186 0.9809756 0.9815396
#> 3 0.9755081 0.9601351 0.9531781 0.9587451 0.9550871
#> 4 0.9522316 0.9364447 0.9296570 0.9322120 0.9310612

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM