简体   繁体   中英

Map nested data by row r

I have data that look like this (thanks once again dput!):

dat <- structure(list(vars = c("var_1", "var_2"), data = list(structure(list(
  time = 1:10, value = c(1:10
  )), row.names = c(NA, -10L), class = c("tbl_df", "tbl", "data.frame"
  )), structure(list(time = 1:10, value = c(11:20
  )), row.names = c(NA, -10L), class = c("tbl_df", "tbl", "data.frame"
  ))), mu = c(1, 2), stdev = c(1,2)), class = c("tbl_df", "tbl", "data.frame"),
  row.names = c(NA,-2L))

I am trying to mutate an extra column which maps a function over each row. eg calculate dnorm for each element of the nested variable in dat$data[[1]]$value using dat$mu[1] and dat$stdev[1] and the go on to do the same for row two.

The column I would like to mutate is a tibble [10 x 1] for each row containing this as the output:

dnorm(dat$data[[1]]$value, mean = dat$mu[1], sd = dat$stdev[1])
dnorm(dat$data[[2]]$value, mean = dat$mu[2], sd = dat$stdev[2])

Things I have tried that don't work but might be close?:

# This alternates between mean and stdev for each element of each nested variable
dat_1 <- dat %>% 
  mutate(z = map(data, ~ dnorm(.x$value, mean = dat$mu, sd = dat$stdev)))
# apply by row has structure issues
dat_2 <- dat %>% 
  apply(MARGIN = 1, function(x){
  mutate(x, z = map(data, ~ dnorm(.x$value, mean = dat$mu, sd = dat$stdev)))
    })

a basic map function like this dat_3 <- dat %>% mutate(sigma = map(data, ~ sum(.x$value))) works fine without referencing other values in the df. This is early days for me using nested data and map in this way - been looking at the documentation for all the map functions to try solve this but no luck yet! If that's clear as mud I can try clarify - thanks in advance!

We can use a parallel map:

library(purrr)
library(dplyr)

expected_out1 <- dnorm(dat$data[[1]]$value, mean = dat$mu[1], sd = dat$stdev[1])
expected_out2 <- dnorm(dat$data[[2]]$value, mean = dat$mu[2], sd = dat$stdev[2])

out <- 
  dat %>% 
  mutate(z = pmap(list(map(data, "value"), mu, stdev), dnorm))

all.equal(out$z, list(expected_out1, expected_out2))
# [1] TRUE

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM