如何在R中应用多参数功能?

时间:2011-11-23 18:17:56

标签: r apply

我有以下数据框和矢量。

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

> v
 [1] 1 2 3

我想将以下函数应用于该数据框中的每个 ROW ,以便将v添加到y的每个 ROW 中:

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

...为了获得这些结果:

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

mapply将该函数应用于 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

我已经尝试过调换数据框,以便将函数应用于行而不是列,但mapply会在转置后给出奇怪的结果:

> 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

...帮助?

############################编辑################## #######

感谢所有答案!我正在学习大量新的R功能,这是我以前从未见过的,这太棒了。

我想稍微澄清一下我之前的问题。我真正要问的是一个更普遍的问题 - 如何将多参数函数应用于R中的每一行(此刻,我很想得出结论我应该使用循环,但我想弄清楚是否有可能,仅供将来参考...)(我也有目的地避免显示我正在使用的代码,因为它有点混乱)。

我尝试使用扫描功能,但我收到以下错误:

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"

但是当我尝试应用扫描......

> 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

当我从此测试示例中删除n参数时,扫描工作正常。这告诉我除非提供给扫描的所有参数与t向量的列数相同,或者长度为1,否则不能使用扫描。如果我错了,请纠正我...

5 个答案:

答案 0 :(得分:3)

你要求用“+”函数“扫过”y行:

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

答案 1 :(得分:2)

我认为你不需要mapply。只需直接使用t(),您就可以根据需要使用rep()进行回收匹配:

> 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 :(得分:2)

如果您的实际问题确实不比此复杂,您可以利用R的回收规则。您需要首先转置y,然后添加,然后转置结果,因为R矩阵存储在column-major order中。

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

答案 3 :(得分:0)

如何使用申请?

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

我不知道为什么apply会将行作为columms返回,因此需要调换它。

答案 4 :(得分:0)

我会毫不犹豫地看一下plyr包的mdply。这正是你想做的事情:

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