Dany:

library(tidyverse)
df <- data.frame(est = c(1.36, -0.03),
                 std = c(0.16, 0.18))
df
#     est  std
# 1  1.36 0.16
# 2 -0.03 0.18

Chcę wykonać następujące czynności:

exp(df[1, 1] + qnorm(c( 0.025, 0.5, 0.975))*df[1, 2])
# [1] 2.847398 3.896193 5.331295
exp(df[2, 1] + qnorm(c( 0.025, 0.5, 0.975))*df[2, 2])
# [1] 0.6819537 0.9704455 1.3809802

Aby skończyć z następującymi df:

df_final
#     est  std        or        ll       ul
# 1  1.36 0.16 2.8473980 3.8961930 5.331295
# 2 -0.03 0.18 0.6819537 0.9704455 1.380980

Nie jestem pewien, dlaczego to nie zadziała:

df[c("or", "ll", "ul")] <- map2(df %>% select(est),
                               df %>% select(std), ~ exp(.x + qnorm(c( 0.025, 0.5, 0.975))*.y))

Jakieś pomysły? dzięki

1
user63230 26 styczeń 2022, 21:20

2 odpowiedzi

Możemy użyć pmap

library(purrr)
library(dplyr)
pmap_dfr(df, ~ exp(..1 + qnorm(c(0.025, 0.5, 0.975)) * ..2) %>% 
        as.list %>% 
        setNames(c('or', 'll', 'ul'))) %>% 
  bind_cols(df, .)

-wynik

  est  std        or        ll       ul
1  1.36 0.16 2.8473985 3.8961933 5.331295
2 -0.03 0.18 0.6819537 0.9704455 1.380980

W poście OP jest selectkolumna, która nadal jest data.frame/tibble z pojedynczą kolumną. Zamiast tego należy go wyodrębnić jako vector, tj. z pull. Kiedy mamy data.frame, jednostką zapętlenia jest kolumna, a nie wiersze, tj.

df[c("or", "ll", "ul") <-  map2(df %>% pull(est),
                               df %>% pull(std), 
     ~ exp(.x + qnorm(c( 0.025, 0.5, 0.975))*.y)) %>% 
       invoke(rbind, .)

Lub może użyć dapply

library(collapse)
f1 <- function(x) setNames(exp(x[1] + 
    qnorm(c(0.025, 0.5, 0.975)) * x[2]), c('or', 'll', 'ul'))
cbind(df, dapply(df, MARGIN = 1, f1))
  est  std        or        ll       ul
1  1.36 0.16 2.8473985 3.8961933 5.331295
2 -0.03 0.18 0.6819537 0.9704455 1.380980
1
akrun 26 styczeń 2022, 21:46
Dzięki, nie sądziłem, że potrzebuję pull, ponieważ nie zrobiłem tego tutaj: stackoverflow.com/a/69379945 /4083743
 – 
user63230
26 styczeń 2022, 21:33
Kiedy robisz map(df, ~ .x), jednostka jest kolumną, więc zapętla się nad kolumną. W przypadku map2 potrzebujesz obu „est”, „std” dla każdego odpowiadającego wiersza
 – 
akrun
26 styczeń 2022, 21:34
To był inny przypadek, gdy masz więcej niż jedną kolumnę i chcesz zastosować funkcję w odpowiednich kolumnach. Tutaj Twoim celem nie jest zastosowanie funkcji do każdej kolumny jako całości, ale do wierszy
 – 
akrun
26 styczeń 2022, 21:39

W bazie R możesz użyć:

a <- exp(df[[1]] + t(qnorm(c( 0.025, 0.5, 0.975)) %o% df[[2]])) 
cbind(df, setNames(data.frame(a),c('or', 'll', 'ul')))

    est  std        or        ll       ul
1  1.36 0.16 2.8473985 3.8961933 5.331295
2 -0.03 0.18 0.6819537 0.9704455 1.380980
0
Onyambu 26 styczeń 2022, 21:43