Этот вопрос касается работы на языке tidyverse
. Я пытаюсь использовать tidyr::nest
и purrr:map2
для выполнения двумерной функции над двумя столбцами tibble
, заменяя их двумя другими столбцами, которые являются результатом этой двумерной функции. Операция заключается в вычислении RO C на основе значений statisti c в H0
и H1
, что дает два новых значения (то есть столбцы) FPR
и TPR
. Вот рабочий пример:
library(tidyverse)
library(purrr)
# function to compute the rejection rates
get_reject_freq <- function(Tstat, th_vec, twosided=T) {
# Tstat is a vector, th could be a vector of thresholds threshold
if (twosided) Tstat <- abs(Tstat)
sapply(th_vec, function(th) mean(Tstat > th))
}
# function to compute the ROC
get_ROC <- function(T0, T1, twosided=T) {
T0_sorted <- sort(unique(T0), decreasing = T)
tibble(FPR = get_reject_freq(T0, T0_sorted, twosided = twosided),
TPR = get_reject_freq(T1, T0_sorted, twosided = twosided))
}
n = m = 15
run_sims_one_iter <- function(j) {
x = rt(n, df=5, ncp=0)
y = list(H0=rt(m, df=5, ncp=0), H1=rt(m, df=5, ncp=1))
result = NULL
for (h in c("H0","H1")) {
result[[h]] = tibble(method="t_test", H=h,
test_stat=t.test(x,y[[h]])$statistic) %>%
add_row(method="wilcoxon", H=h,
test_stat=wilcox.test(x,y[[h]], alternative = "two.sided")$statistic, )
}
return( bind_rows(result) )
}
result = bind_rows( lapply(1:100, run_sims_one_iter) )
#### The following can hopefully be improved ###
temp = result %>%
group_by(method,H) %>%
nest() %>%
pivot_wider(names_from = H, values_from = data) %>%
ungroup()
roc_results = bind_rows(
lapply(1:nrow(temp), function(i) {
get_ROC( temp[[i,"H0"]]$test_stat, temp[[i,"H1"]]$test_stat) %>%
add_column(method = temp[i,]$method)
}
))
Строка
temp = result %>%
group_by(method,H) %>%
nest() %>%
pivot_wider(names_from = H, values_from = data) %>%
ungroup()
производит вывод вида:
# A tibble: 2 x 3
method H0 H1
<chr> <list> <list>
1 t_test <tibble [100 × 1]> <tibble [100 × 1]>
2 wilcoxon <tibble [100 × 1]> <tibble [100 × 1]>
Код должен работать для каждой строки, принимая два столбца в столбцах H0
и H1
, передавая их через функцию get_ROC
и заменяя их столбцами FPR
и TPR
, а затем unnest
всем. Требуемый roc_result
, сгенерированный вышеуказанным кодом, равен
roc_results
# A tibble: 157 x 3
FPR TPR method
<dbl> <dbl> <chr>
1 0.03 0.76 t_test
2 0.04 0.77 t_test
3 0.07 0.82 t_test
...
В идеале я хотел бы заменить конструкцию temp
и roc_results
одной строкой вида:
temp = result %>%
group_by(method,H) %>%
nest() %>%
pivot_wider(names_from = H, values_from = data) %>%
ungroup() %>%
mutate(res=map2(unlist(H0), unlist(H1), get_ROC)) %>% unnest(res)
Но это не работает. Я предполагаю, что проблема может заключаться в том, что размер вывода get_ROC
может меняться для каждой строки (?). Любая идея, как я могу выполнить все операции, используя tidyverse
подход.