我的数据(~1000 行)如下所示:
head(data)
alt alb alp alt_zscore alb_zscore alp_zscore
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 11 2.60 9 -1.54 -7.82 -0.949
2 12 5.37 86.3 -1.45 -0.351 2.31
3 15.7 4.67 28 -1.09 -2.24 -0.148
4 7 4.43 171. -1.93 -2.89 5.87
5 14.5 3.75 12 -1.20 -4.72 -0.822
6 17.5 3.70 82.5 -0.915 -4.86 2.15
每个变量列(即
alt
、alb
、alp
)都有相应的 z 分数列(alt_zscore
、alb_zscore
、alp_zscore
)。
在我之前的代码中,我告诉 R,对于每个 z 评分列,如果观测值比平均值低 1 个标准差以上,则取 z 评分观测值的绝对值;如果不符合标准,则给它 0。(我这样做的原因是因为稍后在我的代码中,我将所有这些 z 评分观察结果添加到另一列中。)
这是我之前的代码:
name <- c("alt_zscore", "alb_zscore", "alp_zscore")
stdev <- 1
lf <- list(
\(x) ifelse(x <= -stdev, abs(x), 0),
\(x) ifelse(x <= -stdev, abs(x), 0),
\(x) ifelse(x <= -stdev, abs(x), 0)
) %>%
setNames(name)
我这样做的原因是我可以创建一个新列“total_score”,它是符合我的标准的所有 z 分数的总和。
data <- data %>%
mutate(total_score = rowSums(across(all_of(name), ~ lf[[cur_column()]](.)), na.rm = TRUE))
现在,我想做的是告诉 R,对于每个“常规”列(即,这里我指的是“alt”,而不是“alt_zscore”),如果观察值小于该列的第 25 个百分位数,然后取其对应的 z 得分列的绝对值 (alt_zscore);否则,给它一个零。
我正在尝试修改现有代码来执行此操作,但运气不佳。任何帮助将不胜感激。谢谢!
您可以使用
across()
+ cur_column()
:
library(dplyr)
df %>%
mutate(across(alt:alp,
~ if_else(.x < quantile(.x, .25), abs(get(paste0(cur_column(), "_zscore"))), 0),
.names = "{.col}_new"))
# alt alb alp alt_zscore alb_zscore alp_zscore alt_new alb_new alp_new
# 1 11.0 2.60 9.0 -1.540 -7.820 -0.949 1.54 7.82 0.949
# 2 12.0 5.37 86.3 -1.450 -0.351 2.310 0.00 0.00 0.000
# 3 15.7 4.67 28.0 -1.090 -2.240 -0.148 0.00 0.00 0.000
# 4 7.0 4.43 171.0 -1.930 -2.890 5.870 1.93 0.00 0.000
# 5 14.5 3.75 12.0 -1.200 -4.720 -0.822 0.00 0.00 0.822
# 6 17.5 3.70 82.5 -0.915 -4.860 2.150 0.00 4.86 0.000
对于您的第一个任务,不需要函数列表 (
lf
),因为所有函数都是相同的。
df %>%
mutate(total_score = rowSums(across(alt:alp, ~ ifelse(.x <= -1, abs(.x), 0)), na.rm = TRUE))
df <- read.table(text =
" alt alb alp alt_zscore alb_zscore alp_zscore
1 11 2.60 9 -1.54 -7.82 -0.949
2 12 5.37 86.3 -1.45 -0.351 2.31
3 15.7 4.67 28 -1.09 -2.24 -0.148
4 7 4.43 171. -1.93 -2.89 5.87
5 14.5 3.75 12 -1.20 -4.72 -0.822
6 17.5 3.70 82.5 -0.915 -4.86 2.15")