让我们考虑
markers
及其变异系数 (cv
) 和三个参考 cv (rcv
):
初始数据:
marker cv rcv1 rcv2 rcv3
<chr> <dbl> <dbl> <dbl> <dbl>
1 AAA 7 10 8 5
2 BBB 4 5 3 1
3 CCC 11 20 15 12
4 DDD 8 7 5 2
我想改变三个新变量:
rcv_value
:大于rcv
的最接近的
cv
rcv_name
:该rcv_value
cv_conclusion
:
cv
低于 rcvs
cv
高于最高 rcv
所需输出:
marker cv rcv1 rcv2 rcv3 rcv_value rcv_name cv_conclusion
<chr> <dbl> <dbl> <dbl> <dbl> <dbl> <chr> <chr>
1 AAA 7 10 8 5 8 rcv2 ok
2 BBB 4 5 3 1 5 rcv1 ok
3 CCC 11 20 15 12 12 rcv3 ok
4 DDD 8 7 5 2 7 rcv1 ko
注意:我的真实数据有超过 100 个
markers
和大约 10 个不同的 rcv
。rcv_name
中获取rcv_value
(使用mutate
和case_when
)。
感谢您的帮助。
数据:
dat0 <-
structure(list(marker = c("AAA", "BBB", "CCC", "DDD"), cv = c(7,
4, 11, 8), rcv1 = c(10, 5, 20, 7), rcv2 = c(8, 3, 15, 5), rcv3 = c(5,
1, 12, 2)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -4L))
你可以试试这个:
library(dplyr)
dat0 %>%
rowwise() %>%
mutate(rcv_value = {
x <- c_across(rcv1:rcv3)
x[order(abs(x - cv), -x)][1]
}) %>%
ungroup() %>%
mutate(
rcv_name = do.call(coalesce, across(rcv1:rcv3, ~ ifelse(.x == rcv_value, cur_column(), NA))),
cv_conclusion = ifelse(rcv_value >= cv, "ok", "ko")
)
# # A tibble: 4 × 8
# marker cv rcv1 rcv2 rcv3 rcv_value rcv_name cv_conclusion
# <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <chr> <chr>
# 1 AAA 7 10 8 5 8 rcv2 ok
# 2 BBB 4 5 3 1 5 rcv1 ok
# 3 CCC 11 20 15 12 12 rcv3 ok
# 4 DDD 8 7 5 2 7 rcv1 ko
tidyr::pivot_longer()
,然后dplyr::mutate(.by = marker)
按组执行这些操作,然后tidyr::pivot_wider()
将数据恢复到原始形状。
library(dplyr)
library(tidyr)
dat0 |>
pivot_longer(
-c(marker, cv),
names_to = "rcv"
) |>
mutate(
rcv_value = min(value[value > cv]),
cv_conclusion = if_else(is.infinite(rcv_value), "ko", "ok"),
rcv_value = if_else(is.infinite(rcv_value), max(value), rcv_value),
rcv_name = rcv[rcv_value == value],
.by = marker
) |>
pivot_wider(
id_cols = c(marker, cv, rcv_value, rcv_name, cv_conclusion),
names_from = rcv,
values_from = value
) |>
select(
# does not drop columns just changes order to specified one
marker, cv, rcv1:rcv3, rcv_value:cv_conclusion
)
# # A tibble: 4 × 8
# marker cv rcv1 rcv2 rcv3 rcv_value rcv_name cv_conclusion
# <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <chr> <chr>
# 1 AAA 7 10 8 5 8 rcv2 ok
# 2 BBB 4 5 3 1 5 rcv1 ok
# 3 CCC 11 20 15 12 12 rcv3 ok
# 4 DDD 8 7 5 2 7 rcv1 ko
如果您可以为
rcv1:rcv3
列中的每个标记建立联系,则您必须指定您想要 rcv_name
说的内容。如果您只想要第一个值,您可以将该行更改为 rcv_name = rcv[rcv_value == value][1]
。或者,您可以创建一个列表列来存储所有值,例如list(rcv[rcv_value == value])
,或将它们粘贴在一起,例如rcv_name = paste(rcv[rcv_value == value], collapse = ",")
创建类似 "rcv2,rcv3"
的列。