How to apply a multiparameter function in R?

I have the following data frame and vector.

> y v1 v2 v3 1 1 6 43 2 4 7 5 3 0 2 32 > v [1] 1 2 3 

I want to apply the following function to each ROW in this data frame, so v is added to each ROW y:

 x <- function(vector1,vector2) { x <- vector1 + vector2 } 

... to get THESE results:

  v1 v2 v3 1 2 8 46 2 5 9 8 3 1 4 35 

mapply applies the function to COLUMNS :

 > z <- mapply(x, y, MoreArgs=list(vector2=v)) > z v1 v2 v3 [1,] 2 7 44 [2,] 6 9 7 [3,] 3 5 35 

I tried to rearrange the data frame so that the function was applied to rows, not columns, but mapply gives me weird results after transposition:

 > transposed <- t(y) > transposed [,1] [,2] [,3] v1 1 4 0 v2 6 7 2 v3 43 5 32 > z <- mapply(x, transposed, MoreArgs=list(vector2=v)) > z [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [1,] 2 7 44 5 8 6 1 3 33 [2,] 3 8 45 6 9 7 2 4 34 [3,] 4 9 46 7 10 8 3 5 35 

... Help?

############################### EDIT ##################### ######

Thanks for answers! I am exploring many new R functions that I have never seen before, which is fantastic.

I want to clarify my previous question a bit. What I'm really asking is a much more general question - how to apply a multi-parameter function to every line in R (at the moment I am tempted to conclude that I should just use a loop, but I would like to find out if this is possible, only for future reference ...) (I also purposefully refrained from showing the code I'm working with, as this is pretty dirty).

I tried to use the sweep function as suggested, but I get the following error:

 testsweep <- function(vector, z, n) { testsweep <- z } > n <- names(Na_exp) > n [1] "NaCl.10000.2hr.AVG_Signal" "NaCl.10000.4hr.AVG_Signal" > t <- head(Li_fcs,n=1) > t LiCl.1000.1hr.FoldChange LiCl.2000.1hr.FoldChange LiCl.5000.1hr.FoldChange [1,] -0.05371838 -0.1010928 -0.01939986 LiCl.10000.1hr.FoldChange LiCl.1000.2hr.FoldChange [1,] 0.1275617 -0.107154 LiCl.2000.2hr.FoldChange LiCl.5000.2hr.FoldChange [1,] -0.06760782 -0.09770226 LiCl.10000.2hr.FoldChange LiCl.1000.4hr.FoldChange [1,] -0.1124188 -0.06140386 LiCl.2000.4hr.FoldChange LiCl.5000.4hr.FoldChange [1,] -0.04323497 -0.04275953 LiCl.10000.4hr.FoldChange LiCl.1000.8hr.FoldChange [1,] 0.03633496 0.01879461 LiCl.2000.8hr.FoldChange LiCl.5000.8hr.FoldChange [1,] 0.257977 -0.06357423 LiCl.10000.8hr.FoldChange [1,] 0.07214176 > z <- colnames(Li_fcs) > z [1] "LiCl.1000.1hr.FoldChange" "LiCl.2000.1hr.FoldChange" [3] "LiCl.5000.1hr.FoldChange" "LiCl.10000.1hr.FoldChange" [5] "LiCl.1000.2hr.FoldChange" "LiCl.2000.2hr.FoldChange" [7] "LiCl.5000.2hr.FoldChange" "LiCl.10000.2hr.FoldChange" [9] "LiCl.1000.4hr.FoldChange" "LiCl.2000.4hr.FoldChange" [11] "LiCl.5000.4hr.FoldChange" "LiCl.10000.4hr.FoldChange" [13] "LiCl.1000.8hr.FoldChange" "LiCl.2000.8hr.FoldChange" [15] "LiCl.5000.8hr.FoldChange" "LiCl.10000.8hr.FoldChange" 

But when I try to apply a scan ...

 > test <- sweep(t, 2, z, n, FUN="testsweep") Error in if (check.margin) { : argument is not interpretable as logical In addition: Warning message: In if (check.margin) { : the condition has length > 1 and only the first element will be used 

When I remove the n parameter from this test case, the sweep works fine. This tells me that the sweep cannot be used if all the parameters provided for the sweep are not equal to the number of columns, like vector t, or length 1. Please correct me if I am wrong ...

+6
source share
5 answers

You ask to "sweep" v along the y lines using the "+" function:

  sweep(y, 1, v, FUN="+") v1 v2 v3 1 2 7 44 2 6 9 7 3 3 5 35 
+3
source

I do not think you need to mapply here. Just use t() directly or you can use rep() to make the recycling fit as you want:

 > set.seed(1) > mat <- matrix(sample(1:100, 9, TRUE), ncol = 3) > vec <- 1:3 > > mat [,1] [,2] [,3] [1,] 27 91 95 [2,] 38 21 67 [3,] 58 90 63 #Approach 1 using t() > ans1 <- t(t(mat) + vec) #Approach 2 using rep() > ans2 <- mat + rep(vec, each = nrow(mat)) #Are they the same? > identical(ans1, ans2) [1] TRUE #Hurray! > ans1 [,1] [,2] [,3] [1,] 28 93 98 [2,] 39 23 70 [3,] 59 92 66 
+2
source

If your actual problem is really no more complicated, you can use the disposal rules of R. First you need to transfer y , then add and then transfer the result, because the matrices R are stored in column order .

 t(t(y)+v) v1 v2 v3 1 2 8 46 2 5 9 8 3 1 4 35 
+2
source

How about using?

  t(apply(y, 1, function(x) x + v)) [,1] [,2] [,3] [1,] 2 8 46 [2,] 5 9 8 [3,] 1 4 35 

I do not know why the application returns the string as columms, so it needs to be transposed.

0
source

I would try looking at mdply to form the plyr package. This is exactly what you want to do:

 mdply(data.frame(mean = 1:5, sd = 1:5), rnorm, n = 2) 
0
source

Source: https://habr.com/ru/post/902237/


All Articles