Given:
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
I want to do the following:
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
To end up with the following 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
I am not sure why this won't work:
df[c("or", "ll", "ul")] <- map2(df %>% select(est),
df %>% select(std), ~ exp(.x qnorm(c( 0.025, 0.5, 0.975))*.y))
any ideas? thanks
CodePudding user response:
We may use 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, .)
-output
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
In the OP's post, it is select
ing the column, which is still a data.frame/tibble
with single column. Instead it should be extracted as a vector
i.e. with pull
. When we have a data.frame
, the unit for looping is column and not rows i.e.
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, .)
Or may use 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
CodePudding user response:
in base R you could use:
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