2011-11-23 60 views
6

我有以下数据框和向量。如何在R中应用多参数函数?

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

> v 
[1] 1 2 3 

我想下面的函数应用到每个ROW在该数据帧时,v被添加到每个Y行的

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

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

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

mapply应用功能

> 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,否则不能使用扫描。请纠正我,如果我错了...

回答

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将行作为列返回,因此需要进行转置。

+0

我会defintely看看mdply形式的plyr包。这正是你所要求的。 –

+0

我会明白地看看plyr软件包中的mdply。这正是你所要求的。 –

3

你问到“扫” V跨越y行用“+”功能:

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

我想'MARGIN'必须是2,因为你想把'v'应用到'y'的列上。 –

+0

是的。我也这么认为,但我们都错了。 –

+0

我认为扫描正是我所期待的。这个问题实际上比添加矢量更复杂 - 我只是用它作为例子,因为它是想到的最简单的东西。我真正想要的是一种轻松快速地将多参数函数应用于每一行的方法 - 这似乎是扫描所做的。所以谢谢! –

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 
+0

+ 1通过与'每个='''代表手动回收。 –

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 
0

我会明白地看看mlyply形式的plyr包。这正是你想要做的:

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