如何在R中应用多参数函数?
我有下面的数据帧和向量如何在R中应用多参数函数?,r,apply,R,Apply,我有下面的数据帧和向量 > y v1 v2 v3 1 1 6 43 2 4 7 5 3 0 2 32 > v [1] 1 2 3 我想对该数据帧中的每一行应用以下函数,以便将v添加到y的每一行: mapply将函数应用于列: >z v1 v2 v3 [1,] 2 7 44 [2,] 6 9 7 [3,] 3 5 35 我曾尝试转置数据帧,以便将函数应用于行而不是列,但mapply在转置后给了我奇怪的结果: > transposed <
> y
v1 v2 v3
1 1 6 43
2 4 7 5
3 0 2 32
> v
[1] 1 2 3
我想对该数据帧中的每一行应用以下函数,以便将v添加到y的每一行:
mapply将函数应用于列:
>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
>转置
[,1] [,2] [,3]
v1 14 0
v2 6 7 2
v3 43 5 32
>z 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中的每一行(目前,我很想得出结论,我应该只使用循环,但我想知道这是否可能,仅供将来参考…)(我还特意避免显示我正在使用的代码,因为它有点凌乱)
我尝试按照建议使用sweep函数,但出现以下错误:
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"
testsweep t
LiCl.1000.1hr.FoldChange LiCl.2000.1hr.FoldChange LiCl.5000.1hr.FoldChange
[1,] -0.05371838 -0.1010928 -0.01939986
LiCl.10000.1小时折叠更改LiCl.1000.2小时折叠更改
[1,] 0.1275617 -0.107154
LiCl.2000.2hr.FoldChange LiCl.5000.2hr.FoldChange
[1,] -0.06760782 -0.09770226
LiCl.10000.2小时折叠更改LiCl.1000.4小时折叠更改
[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 z
[1] “LiCl.1000.1小时折叠更改”“LiCl.2000.1小时折叠更改”
[3] “LiCl.5000.1小时折叠更改”“LiCl.10000.1小时折叠更改”
[5] “LiCl.1000.2小时折叠更改”“LiCl.2000.2小时折叠更改”
[7] “LiCl.5000.2小时折叠更改”“LiCl.10000.2小时折叠更改”
[9] “LiCl.1000.4hr.FoldChange”“LiCl.2000.4hr.FoldChange”
[11] “LiCl.5000.4hr.折叠更改”“LiCl.10000.4hr.折叠更改”
[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
>测试1,仅使用第一个元素
当我从这个测试示例中删除n参数时,sweep工作正常。这向我建议,除非为sweep提供的所有参数的列数与t向量相同,或者长度为1,否则不能使用sweep。如果我弄错了,请纠正我…使用apply如何
t(apply(y, 1, function(x) x + v))
[,1] [,2] [,3]
[1,] 2 8 46
[2,] 5 9 8
[3,] 1 4 35
我不知道为什么apply会将行返回为列,因此需要对其进行转置。您要求使用“+”函数在y行中“扫描”v:
sweep(y, 1, v, FUN="+")
v1 v2 v3
1 2 7 44
2 6 9 7
3 3 5 35
我认为您不需要在这里使用
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
>设置种子(1)
>mat-vec
>垫子
[,1] [,2] [,3]
[1,] 27 91 95
[2,] 38 21 67
[3,] 58 90 63
#使用t()的方法1
>ans1 ans2相同(ans1,ans2)
[1] 真的
#万岁!
>ans1
[,1] [,2] [,3]
[1,] 28 93 98
[2,] 39 23 70
[3,] 59 92 66
如果您的实际问题并不比这更复杂,您可以利用R的循环规则。您需要先将y
转置,然后添加,然后转置结果,因为R矩阵存储在中
我将从plyr包中查看mdply。这正是您想要做的:
mdply(data.frame(mean = 1:5, sd = 1:5), rnorm, n = 2)
我认为
MARGIN
需要为2,因为你想将v
应用于y
的列。我认为sweep正是我想要的。这个问题实际上比仅仅添加向量更复杂-我只是以它为例,因为它是我想到的最简单的事情。我真正想要的是这是一种简单而快速地将多参数函数应用于每一行的方法-这似乎就是sweep所做的。谢谢!不,经过再三考虑,这并没有解决我的问题:sweep似乎无法获取具有任意数量值的向量。抱歉-所以要澄清,我有一个函数作为参数:vector1,vector2,vector3.Vector1和vector2的长度相同。vector3的长度是任意的。我想将此函数应用于矩阵的每一行。但任意长度vector3的存在似乎导致我的代码失败。我得到以下错误:if中的错误(check.margin){:参数不可解释为逻辑。另外:警告消息:In if(check.margin){:条件的长度大于1,并且只使用第一个元素。您的问题听起来更像是代码中某个函数的错误使用,而不是由于向量长度不相等。我们只能猜测这一点。我将明确查看plyr包中的mdply。这正是您要求的。我将定义请看一下plyr包中的mdply。这正是您所要求的。
sweep(y, 1, v, FUN="+")
v1 v2 v3
1 2 7 44
2 6 9 7
3 3 5 35
> 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
t(t(y)+v)
v1 v2 v3
1 2 8 46
2 5 9 8
3 1 4 35
mdply(data.frame(mean = 1:5, sd = 1:5), rnorm, n = 2)