在数据框的每一列上调用 R apply-like 函数,将剩余的列作为参数?
Call R apply-like function on each column of dataframe with the remained columns as argument?
我有一个包含多列的数据框。对于数据框中的每一列,我想在该列上调用一个函数,函数的输入使用数据框中剩余的列。例如,假设我有这个数据和这个接受两个参数的 testFunc:
> df <- data.frame(x=c(1,2), y=c(3,4), z=c(5,6))
> df
x y z
1 1 3 5
2 2 4 6
>
> testfun <- function(a, b){colMeans(a + 2 * b)} # only for illustation
假设我想应用此 testFunc 来循环所有列。这是获得结果的循环。
> for (i in 1:nrow(df)) {
+ Y = matrix(df[, i], ncol = 1)
+ Xmat = df[, -i]
+ result[i, -i] = testfun(Y, Xmat)
+ }
>
> result
[,1] [,2] [,3]
[1,] 0.0 8.5 12.5
[2,] 6.5 0.0 14.5
[3,] 0.0 0.0 0.0
有没有办法在不编写 for 循环的情况下执行此操作,也许使用 apply 函数系列?非常感谢。
我们可以循环遍历 sapply/lapply
中数据集的列序列,提取具有索引的数据集列 Y
和索引上具有 -
的其余列,应用testfun
,根据索引(-i
)分配一个已经初始化的numeric
向量(长度与数据集的列数相同),return vector
和 t
转置 sapply
的输出
v1 <- numeric(ncol(df));
t(sapply(seq_along(df), function(i) {
v1[-i] <- testfun(as.matrix(df[i]), df[-i])
v1
}))
-输出
# [,1] [,2] [,3]
#[1,] 0.0 8.5 12.5
#[2,] 6.5 0.0 14.5
#[3,] 8.5 12.5 0.0
或者可以用 tidyverse
来完成
library(dplyr)
df %>%
summarise(across(everything(), ~ testfun(., select(df, -cur_column()))))
# x y z
#1 8.5 6.5 8.5
#2 12.5 14.5 12.5
我有一个包含多列的数据框。对于数据框中的每一列,我想在该列上调用一个函数,函数的输入使用数据框中剩余的列。例如,假设我有这个数据和这个接受两个参数的 testFunc:
> df <- data.frame(x=c(1,2), y=c(3,4), z=c(5,6))
> df
x y z
1 1 3 5
2 2 4 6
>
> testfun <- function(a, b){colMeans(a + 2 * b)} # only for illustation
假设我想应用此 testFunc 来循环所有列。这是获得结果的循环。
> for (i in 1:nrow(df)) {
+ Y = matrix(df[, i], ncol = 1)
+ Xmat = df[, -i]
+ result[i, -i] = testfun(Y, Xmat)
+ }
>
> result
[,1] [,2] [,3]
[1,] 0.0 8.5 12.5
[2,] 6.5 0.0 14.5
[3,] 0.0 0.0 0.0
有没有办法在不编写 for 循环的情况下执行此操作,也许使用 apply 函数系列?非常感谢。
我们可以循环遍历 sapply/lapply
中数据集的列序列,提取具有索引的数据集列 Y
和索引上具有 -
的其余列,应用testfun
,根据索引(-i
)分配一个已经初始化的numeric
向量(长度与数据集的列数相同),return vector
和 t
转置 sapply
v1 <- numeric(ncol(df));
t(sapply(seq_along(df), function(i) {
v1[-i] <- testfun(as.matrix(df[i]), df[-i])
v1
}))
-输出
# [,1] [,2] [,3]
#[1,] 0.0 8.5 12.5
#[2,] 6.5 0.0 14.5
#[3,] 8.5 12.5 0.0
或者可以用 tidyverse
library(dplyr)
df %>%
summarise(across(everything(), ~ testfun(., select(df, -cur_column()))))
# x y z
#1 8.5 6.5 8.5
#2 12.5 14.5 12.5