R apply() 自定义函数到数据框中的每一行
R apply() custom function to every row in data frame
我正在尝试在整个数据框中逐行应用自定义函数。该函数是使用数据框中报告的汇总统计信息的 t 检验,我想在现有数据框中附加函数的四个输出列(均值差、标准误差、t、p 值)。该函数运行良好,但我不确定where/how 将函数的变量调用到数据框中的列。
这是数据框的示例:
MPAmeans <- data.frame(
group = c("ccfrp","kelp","beach","intertidal"),
MPA_mean = c(935,974,50.8,935),
reference_mean = c(388,388,37.6,266),
sd_MPA = c(208, 488, 85.9, 60),
sd_reference = c(170, 170, 62, 151),
n_MPA = c(3,3,3,3),
n_reference = c(3,3,3,3))
以及我想应用到每一行的函数:
t.test2 <- function(m1,m2,s1,s2,n1,n2,m0=0,equal.variance=FALSE)
{
if( equal.variance==FALSE )
{
se <- sqrt( (s1^2/n1) + (s2^2/n2) )
# welch-satterthwaite df
df <- ( (s1^2/n1 + s2^2/n2)^2 )/( (s1^2/n1)^2/(n1-1) + (s2^2/n2)^2/(n2-1) )
} else
{
# pooled standard deviation, scaled by the sample sizes
se <- sqrt( (1/n1 + 1/n2) * ((n1-1)*s1^2 + (n2-1)*s2^2)/(n1+n2-2) )
df <- n1+n2-2
}
t <- (m1-m2-m0)/se
dat <- c(m1-m2, se, t, 2*pt(-abs(t),df)) #one tailed m2 > m1. Replace with "2*pt(-abs(t),df))" for two tailed.
names(dat) <- c("Difference of means", "Std Error", "t", "p-value")
return(dat)
}
我正在使用 apply(),并在下面列出了对数据框的函数引用...
apply(MPAmeans,
1,
t.test2)
m1=reference_mean,
m2=MPA_mean,
s1=sd_reference,
s2=sd_MPA,
n1=n_reference,
n2=n_MPA
如何 reference/call apply() 中的函数变量,然后将四个新列附加到数据框?
我们可以在循环后使用 lambda 函数 (function(x)
) 一个一个地指定参数,或者创建一个命名的 list
并使用 do.call
apply(MPAmeans[c(3, 2, 5, 4, 7, 6)], 1, function(x)
do.call(t.test2, setNames(as.list(x), as.list(args(t.test2))[1:6])))
-输出
[,1] [,2] [,3] [,4]
Difference of means -547.00000000 -586.0000000 -13.2000000 -6.690000e+02
Std Error 155.09566940 298.3532582 61.1631970 9.381009e+01
t -3.52685541 -1.9641146 -0.2158161 -7.131429e+00
p-value 0.02590082 0.1632975 0.8406800 8.798398e-03
另一种方法是修改现有函数,使其矢量化。
t.test2 <- function(m1,m2,s1,s2,n1,n2,m0=0,equal.variance=FALSE)
{
if(!equal.variance)
{
se <- sqrt( (s1^2/n1) + (s2^2/n2) )
# welch-satterthwaite df
df <- ( (s1^2/n1 + s2^2/n2)^2 )/( (s1^2/n1)^2/(n1-1) + (s2^2/n2)^2/(n2-1) )
} else
{
# pooled standard deviation, scaled by the sample sizes
se <- sqrt( (1/n1 + 1/n2) * ((n1-1)*s1^2 + (n2-1)*s2^2)/(n1+n2-2) )
df <- n1+n2-2
}
t <- (m1-m2-m0)/se
dat <- vapply(seq_len(length(m1)),
function(x){c(m1[x]-m2[x], se[x], t[x], 2*pt(-abs(t[x]),df[x]))},
numeric(4)) #one tailed m2 > m1. Replace with "2*pt(-abs(t),df))" for two tailed.
dat <- t(dat)
dat <- as.data.frame(dat)
names(dat) <- c("Difference of means", "Std Error", "t", "p-value")
return(dat)
}
这种方法允许您为各种输入传递向量,它会为您的输入提供一个长度相等的数据帧。它使用 vapply
函数为每个提供的值 return 一个长度为 4 的向量。
在这种方式下,你可以直接去
t.test2(MPAmeans$reference_mean, MPAmeans$MPA_mean, MPAmeans$sd_reference, MPAmeans$sd_MPA, MPAmeans$n_reference, MPAmeans$n_MPA)
(或您最终调用变量的任何内容)
我正在尝试在整个数据框中逐行应用自定义函数。该函数是使用数据框中报告的汇总统计信息的 t 检验,我想在现有数据框中附加函数的四个输出列(均值差、标准误差、t、p 值)。该函数运行良好,但我不确定where/how 将函数的变量调用到数据框中的列。
这是数据框的示例:
MPAmeans <- data.frame(
group = c("ccfrp","kelp","beach","intertidal"),
MPA_mean = c(935,974,50.8,935),
reference_mean = c(388,388,37.6,266),
sd_MPA = c(208, 488, 85.9, 60),
sd_reference = c(170, 170, 62, 151),
n_MPA = c(3,3,3,3),
n_reference = c(3,3,3,3))
以及我想应用到每一行的函数:
t.test2 <- function(m1,m2,s1,s2,n1,n2,m0=0,equal.variance=FALSE)
{
if( equal.variance==FALSE )
{
se <- sqrt( (s1^2/n1) + (s2^2/n2) )
# welch-satterthwaite df
df <- ( (s1^2/n1 + s2^2/n2)^2 )/( (s1^2/n1)^2/(n1-1) + (s2^2/n2)^2/(n2-1) )
} else
{
# pooled standard deviation, scaled by the sample sizes
se <- sqrt( (1/n1 + 1/n2) * ((n1-1)*s1^2 + (n2-1)*s2^2)/(n1+n2-2) )
df <- n1+n2-2
}
t <- (m1-m2-m0)/se
dat <- c(m1-m2, se, t, 2*pt(-abs(t),df)) #one tailed m2 > m1. Replace with "2*pt(-abs(t),df))" for two tailed.
names(dat) <- c("Difference of means", "Std Error", "t", "p-value")
return(dat)
}
我正在使用 apply(),并在下面列出了对数据框的函数引用...
apply(MPAmeans,
1,
t.test2)
m1=reference_mean,
m2=MPA_mean,
s1=sd_reference,
s2=sd_MPA,
n1=n_reference,
n2=n_MPA
如何 reference/call apply() 中的函数变量,然后将四个新列附加到数据框?
我们可以在循环后使用 lambda 函数 (function(x)
) 一个一个地指定参数,或者创建一个命名的 list
并使用 do.call
apply(MPAmeans[c(3, 2, 5, 4, 7, 6)], 1, function(x)
do.call(t.test2, setNames(as.list(x), as.list(args(t.test2))[1:6])))
-输出
[,1] [,2] [,3] [,4]
Difference of means -547.00000000 -586.0000000 -13.2000000 -6.690000e+02
Std Error 155.09566940 298.3532582 61.1631970 9.381009e+01
t -3.52685541 -1.9641146 -0.2158161 -7.131429e+00
p-value 0.02590082 0.1632975 0.8406800 8.798398e-03
另一种方法是修改现有函数,使其矢量化。
t.test2 <- function(m1,m2,s1,s2,n1,n2,m0=0,equal.variance=FALSE)
{
if(!equal.variance)
{
se <- sqrt( (s1^2/n1) + (s2^2/n2) )
# welch-satterthwaite df
df <- ( (s1^2/n1 + s2^2/n2)^2 )/( (s1^2/n1)^2/(n1-1) + (s2^2/n2)^2/(n2-1) )
} else
{
# pooled standard deviation, scaled by the sample sizes
se <- sqrt( (1/n1 + 1/n2) * ((n1-1)*s1^2 + (n2-1)*s2^2)/(n1+n2-2) )
df <- n1+n2-2
}
t <- (m1-m2-m0)/se
dat <- vapply(seq_len(length(m1)),
function(x){c(m1[x]-m2[x], se[x], t[x], 2*pt(-abs(t[x]),df[x]))},
numeric(4)) #one tailed m2 > m1. Replace with "2*pt(-abs(t),df))" for two tailed.
dat <- t(dat)
dat <- as.data.frame(dat)
names(dat) <- c("Difference of means", "Std Error", "t", "p-value")
return(dat)
}
这种方法允许您为各种输入传递向量,它会为您的输入提供一个长度相等的数据帧。它使用 vapply
函数为每个提供的值 return 一个长度为 4 的向量。
在这种方式下,你可以直接去
t.test2(MPAmeans$reference_mean, MPAmeans$MPA_mean, MPAmeans$sd_reference, MPAmeans$sd_MPA, MPAmeans$n_reference, MPAmeans$n_MPA)
(或您最终调用变量的任何内容)