【发布时间】:2021-02-28 09:37:57
【问题描述】:
我有一个大型数据框,其中包含 40 个问题的回答(代表以下 3 个问题),并且需要计算一个新列,该列是这 40 个回答的复杂函数。由于几乎不可能在mutate 中写出函数,因此我尝试创建一个可以在mutate 中使用的函数f
df <- data.frame(Sex = c(rep("F", 5), rep("M", 5)),
Q1 = sample(0:10, 10, replace=T),
Q2 = sample(0:10, 10, replace=T),
Q3 = sample(0:10, 10, replace=T)
)
f <- function(q1, q2, q3){
y <- q1 + (q2^2) - (q3^3)
return(y)
}
现在使用mutate 创建一个新列可以正常工作。:
df %>%
mutate(newcol = f(Q1, Q2, Q3))
Sex Q1 Q2 Q3 newcol
1 F 10 6 3 19
2 F 0 9 9 -648
3 F 8 1 2 1
4 F 0 4 7 -327
5 F 6 4 1 21
6 M 8 3 3 -10
7 M 2 2 0 6
8 M 10 0 3 -17
9 M 6 9 3 60
10 M 1 7 2 42
也一样
df$newcol <- mapply(f, df$Q1, df$Q2, df$Q3)
但如果我在f 中包含一个简单的if atatement,如下所示
f <- function(q1, q2, q3){
y <- q1 + (q2^2) - (q3^3)
if(y<0){
y <- -y
}
return(y)
}
我的手上立刻就有了灾难:
df %>%
+ mutate(newcol = f(Q1, Q2, Q3))
Sex Q1 Q2 Q3 newcol
1 F 10 6 3 19
2 F 0 9 9 -648
3 F 8 1 2 1
4 F 0 4 7 -327
5 F 6 4 1 21
6 M 8 3 3 -10
7 M 2 2 0 6
8 M 10 0 3 -17
9 M 6 9 3 60
10 M 1 7 2 42
Warning message:
Problem with `mutate()` input `newcol`.
i the condition has length > 1 and only the first element will be used
i Input `newcol` is `f(Q1, Q2, Q3)`.
然而,
df$newcol <- mapply(f, df$Q1, df$Q2, df$Q3)
df
Sex Q1 Q2 Q3 newcol
1 F 10 6 3 19
2 F 0 9 9 648
3 F 8 1 2 1
4 F 0 4 7 327
5 F 6 4 1 21
6 M 8 3 3 10
7 M 2 2 0 6
8 M 10 0 3 17
9 M 6 9 3 60
10 M 1 7 2 42
继续工作。 不幸的是,我的函数中有很多 if,并且有 40 个不同的参数要传递给函数,mapply 的输入变得巨大。如何使用预定义的向量将我的问题传递给 mapply,比如
questions <- c("df$Q1", "df$Q2", "df$Q3")
df$newcol <- mapply(f, questions)
密切相关:我如何定义一个有 40 个参数的函数而不使它跑出页面?
我完全有可能找错了树,如果是这样,我应该如何解决我的问题?
在此先感谢
托马斯·飞利浦
附:这是真正的标准
if(!is.na(df[i, "Q1_Daily_Mean"]) & df[i, "Q1_Daily_Mean"] >= THRESHOLD_MDD_GAD){
anxiety <- TRUE
}
if(!is.na(df[i, "Q2_Daily_Mean"]) & df[i, "Q2_Daily_Mean"] >= THRESHOLD_MDD_GAD){
worry <- TRUE
}
if(anxiety && worry){
anxiety_and_worry <- TRUE
}
if(!is.na(df[i, "Q3_Daily_Mean"]) & df[i, "Q3_Daily_Mean"] >= THRESHOLD_MDD_GAD ){
agitation <- TRUE
}
if(!is.na(df[i, "Q10_Daily_Mean"]) & df[i, "Q10_Daily_Mean"] >= THRESHOLD_MDD_GAD ){
anger <- TRUE
}
if(!is.na(df[i, "Q2_Weekly"]) & df[i, "Q2_Weekly"] >= THRESHOLD_MDD_GAD ){
physical_fatigue <- TRUE
}
if(!is.na(df[i, "Q5_Weekly"]) & df[i, "Q5_Weekly"] >= THRESHOLD_MDD_GAD ){
no_concentration <- TRUE
}
if(!is.na(df[i, "Q7_Weekly"]) & df[i, "Q7_Weekly"] >= THRESHOLD_MDD_GAD ){
disturbed_sleep <- TRUE
}
if(!is.na(df[i, "Q13_Weekly"]) & !is.na(df[i, "Q14_Weekly"]) &
!is.na(df[i, "Q15_Weekly"]) & !is.na(df[i, "Q16_Weekly"]) &
!is.na(df[i, "Q17_Weekly"]) &
max( df[i, "Q13_Weekly"], df[i, "Q14_Weekly"],
df[i, "Q15_Weekly"], df[i, "Q16_Weekly"],
df[i, "Q17_Weekly"] ) >= THRESHOLD_MDD_GAD){
max_function <- TRUE
}
sum_of_symptoms_7 <- anxiety + worry + agitation + anger +
physical_fatigue + no_concentration + disturbed_sleep
if (anxiety_and_worry && (sum_of_symptoms_7 >= CRITERIA_NEEDED_GAD) && max_function){
# Generalized Anxiety Disorder
df[i, GAD_DESCRIPTPR_EML] <- TRUE
}
【问题讨论】:
-
y <- abs(y)应该修复它或使用ifelse(y < 0, -y, y) -
如果主要关心的是参数的数量(40 确实过多!)考虑tidying 你的数据:有两列,一列用于问题编号,一列用于响应,而不是每个问题一列.或者,您可以将条件作为命名列表传递,列表的名称标识新列名,列表的值给出表达式以评估以填充新列
标签: r dplyr user-defined-functions