将 lapply 用于矩阵上的函数,其中列作为 R 中的元素
using lapply for a function on a matrix with columns as elements in R
我还是 R 的新手,所以如果这是基本问题,请原谅。
我有以下数据框:
df <- data.frame(a=c(2,4,6,8), x = c(1,0,0,0), y=c(0,1,0,0), z=c(0,0,0,1))
> df
a x y z
1 2 1 0 0
2 4 0 1 0
3 6 0 0 0
4 8 0 0 1
我将函数 sumfunc 定义为
sumfunc <- function(a,x,y,z){a*2+x+y-z}
因此每一行都有输入 a、x、y、z,我希望得到一个包含 4 个元素的向量。
- 元素 1 = 5 (2*2+1+0-0)
- 元素2 = 9 (4*2+0+1-0)
- 元素 3 = 12(6*2+0+0-0)
- 元素 4 = 15 (8*2+0+0-1)
我试过使用
abc <- lapply(df$a, FUN=sumfunc, x=df$x, y=df$y, z=df$z)
但这并没有给我想要的输出。应用家庭功能的建议适合我的用例。
非常感谢!
我想我找到并回答了,虽然我不确定这是否是最合适的方式
abc <- apply(X=as.data.frame(df$a), MARGIN=2, FUN=sumfunc, x=df$x,y=df$y, z=df$z)
这里有几种方法。您不需要 apply
因为 R 是矢量化的:
with(df, a*2+x+y-z)
# [1] 5 9 12 15
with(df, sumfunc(a,x,y,z))
# [1] 5 9 12 15
如果你真的要用apply
):
apply(df, 1, function(x) sumfunc(x[1], x[2], x[3], x[4]))
# [1] 5 9 12 15
现在是使用的好时机mapply
:
mapply(sumfunc, df$a, df$x, df$y, df$z)
# [1] 5 9 12 15
如果您想以编程方式使用它,并且列名发生变化或参数数量发生变化,那么您也可以这样使用它:
do.call(mapply, c(list(FUN=sumfunc), df))
# [1] 5 9 12 15
如果您想要,请在此处保留 data.frame 一个简单的解决方案
library(dplyr)
df %>%
mutate(sum = sumfunc(a,x,y,z))
a x y z sum
1 2 1 0 0 5
2 4 0 1 0 9
3 6 0 0 0 12
4 8 0 0 1 15
然后 return 一个向量
df %>%
mutate(sum = sumfunc(a,x,y,z)) %>%
pull(sum)
[1] 5 9 12 15
我们可以使用 pmap
library(purrr)
pmap_dbl(df, sumfunc)
[1] 5 9 12 15
或者可以Vectorize
函数并使用do.call
do.call(Vectorize(sumfunc), df)
[1] 5 9 12 15
这是另一个简单的解决方案:
library(purrr)
exec(sumfunc, !!!df)
[1] 5 9 12 15
我还是 R 的新手,所以如果这是基本问题,请原谅。 我有以下数据框:
df <- data.frame(a=c(2,4,6,8), x = c(1,0,0,0), y=c(0,1,0,0), z=c(0,0,0,1))
> df
a x y z
1 2 1 0 0
2 4 0 1 0
3 6 0 0 0
4 8 0 0 1
我将函数 sumfunc 定义为
sumfunc <- function(a,x,y,z){a*2+x+y-z}
因此每一行都有输入 a、x、y、z,我希望得到一个包含 4 个元素的向量。
- 元素 1 = 5 (2*2+1+0-0)
- 元素2 = 9 (4*2+0+1-0)
- 元素 3 = 12(6*2+0+0-0)
- 元素 4 = 15 (8*2+0+0-1)
我试过使用
abc <- lapply(df$a, FUN=sumfunc, x=df$x, y=df$y, z=df$z)
但这并没有给我想要的输出。应用家庭功能的建议适合我的用例。
非常感谢!
我想我找到并回答了,虽然我不确定这是否是最合适的方式
abc <- apply(X=as.data.frame(df$a), MARGIN=2, FUN=sumfunc, x=df$x,y=df$y, z=df$z)
这里有几种方法。您不需要 apply
因为 R 是矢量化的:
with(df, a*2+x+y-z)
# [1] 5 9 12 15
with(df, sumfunc(a,x,y,z))
# [1] 5 9 12 15
如果你真的要用apply
):
apply(df, 1, function(x) sumfunc(x[1], x[2], x[3], x[4]))
# [1] 5 9 12 15
现在是使用的好时机mapply
:
mapply(sumfunc, df$a, df$x, df$y, df$z)
# [1] 5 9 12 15
如果您想以编程方式使用它,并且列名发生变化或参数数量发生变化,那么您也可以这样使用它:
do.call(mapply, c(list(FUN=sumfunc), df))
# [1] 5 9 12 15
如果您想要,请在此处保留 data.frame 一个简单的解决方案
library(dplyr)
df %>%
mutate(sum = sumfunc(a,x,y,z))
a x y z sum
1 2 1 0 0 5
2 4 0 1 0 9
3 6 0 0 0 12
4 8 0 0 1 15
然后 return 一个向量
df %>%
mutate(sum = sumfunc(a,x,y,z)) %>%
pull(sum)
[1] 5 9 12 15
我们可以使用 pmap
library(purrr)
pmap_dbl(df, sumfunc)
[1] 5 9 12 15
或者可以Vectorize
函数并使用do.call
do.call(Vectorize(sumfunc), df)
[1] 5 9 12 15
这是另一个简单的解决方案:
library(purrr)
exec(sumfunc, !!!df)
[1] 5 9 12 15