首页 文章

R-如何使用map()到map()

提问于
浏览
0

我需要访问另一个 nest() 函数内的 nest() 函数中的tibble表 .

x <- list( factory = c('a','b','c','d'), cost = c(21,30,44,100))
x <- as.data.frame(x)
x <-  x %>%
        melt('cost','factory')
colnames(x) <- c('cost','client','type')
x <- x %>%
  group_by(client)%>%
  nest()

for (m in 1:4) {
  if(m==1){
    x$scene <- m
    x2 <- x
  }else{
    x3 <- x
    x3$scene <- m
    x2 <- rbind(x2,x3)
  }
}
x2 <- x2 %>%
  group_by(scene) %>%
  nest()

我想要做的是在第一个向量中应用一个函数,如:

test <- function(df){
  df$data %>%
  mutate(increa = cost + 15)
}

x2$data%>%
  map(test)

dput(x2) 结果a:

结构(列表(场景= 1:4,数据=列表(结构(列表(客户端=结构(1L,.Label =“工厂”,类=“因子”)),数据=列表(结构(列表(成本= c) (21,30,44,100),type = c(“a”,“b”,“c”,“d”)),row.names = c(NA,-4L),class = c(“tbl_df “,”tbl“,”data.frame“)))),row.names = c(NA,-1L),class = c(”tbl_df“,”tbl“,”data.frame“)),结构( list(client = structure(1L,.Label =“factory”,class =“factor”),data = list(结构(list(cost = c(21,30,44,100),type = c(“a” ,“b”,“c”,“d”)),row.names = c(NA,-4L),class = c(“tbl_df”,“tbl”,“data.frame”)))),行.names = c(NA,-1L),class = c(“tbl_df”,“tbl”,“data.frame”)),结构(list(client = structure(1L,.Label =“factory”,class = “factor”),data = list(结构(list(cost = c(21,30,44,100),type = c(“a”,“b”,“c”,“d”)),row . names = c(NA,-4L),class = c(“tbl_df”,“tbl”,“data.frame”)))),row.names = c(NA,-1L),class = c(“tbl_df “,”tbl“,”data.frame“)),结构(list(client = structure(1L,.Label =”factory“,class =“factor”),data = list(结构(list(cost = c(21,30,44,100),type = c(“a”,“b”,“c”,“d”)),row .names = c(NA,-4L),class = c(“tbl_df”,“tbl”,“data.frame”)))),row.names = c(NA,-1L),class = c(“ tbl_df“,”tbl“,”data.frame“)))),row.names = c(NA,-4L),class = c(”tbl_df“,”tbl“,”data.frame“))

预期结果:

[[1]]
[[1]]$`factory`
[1] "a" "b" "c" "d"

[[1]]$cost
[1]  21  30  44 100

[[1]]$increa
[1]  36  45  59 115


[[2]]
[[2]]$`factory`
[1] "a" "b" "c" "d"

[[2]]$cost
[1]  21  30  44 100

[[2]]$increa
[1]  36  45  59 115


[[3]]
[[3]]$`factory`
[1] "a" "b" "c" "d"

[[3]]$cost
[1]  21  30  44 100

[[3]]$increa
[1]  36  45  59 115


[[4]]
[[4]]$`factory`
[1] "a" "b" "c" "d"

[[4]]$cost
[1]  21  30  44 100

[[4]]$increa
[1]  36  45  59 115

有人可以帮我解决这个问题吗?

答案

这是我正在寻找的结果:

map(x2$data, function(df) map(df$data, function(df) df <- mutate(df,increa = cost + 15)))

1 回答

  • 0

    为了获得您想要的输出,我认为首先提取您想要的信息级别然后计算新列更容易 . 另一方面,如果你想操纵这个结构中的数据并保留它,那么嵌套调用 mapmutate 是必要的 -

    library(tidyverse)
    

    First solution - extract information and then calculate new column:
    我们可以获得所需的信息水平

    map(x2$data, ~ .x$data) 
    
    # [[1]]
    # [[1]][[1]]
    # # A tibble: 4 x 2
    #    cost type 
    #   <dbl> <chr>
    # 1    21 a    
    # 2    30 b    
    # 3    44 c    
    # 4   100 d    
    # 
    # 
    # [[2]]
    # [[2]][[1]]
    # # A tibble: 4 x 2
    #    cost type 
    #   <dbl> <chr>
    # 1    21 a    
    # 2    30 b    
    # 3    44 c    
    # 4   100 d    
    #
    # ...
    

    由于这是嵌套列表结构,因此需要第二个 map 来计算新列 . 这里 mutate -function应用于每个嵌套数据条目以及附加规范以创建新列inc .

    map(x2$data, ~ map(.x$data, mutate, inc = cost + 15)) 
    
    # [[1]]
    # [[1]][[1]]
    # # A tibble: 4 x 3
    #    cost type    inc
    #   <dbl> <chr> <dbl>
    # 1    21 a        36
    # 2    30 b        45
    # 3    44 c        59
    # 4   100 d       115
    # 
    # 
    # [[2]]
    # [[2]][[1]]
    # # A tibble: 4 x 3
    #    cost type    inc
    #   <dbl> <chr> <dbl>
    # 1    21 a        36
    # 2    30 b        45
    # 3    44 c        59
    # 4   100 d       115
    #
    # ...
    

    使用额外函数 test 可获得相同的结果,该函数将 data.frame 作为输入参数并计算新列:

    test <- function(df){
        mutate(df, increa = cost + 15)
    }
    
    map(x2$data, ~ map(.x$data, test))
    

    Second solution - Manipulate in place
    如果你想保留这个嵌套结构,那么我们在第一个 data 列上使用 mutate ,使用 map ,再次使用 mutatemap

    x2_new <- x2 %>% 
      mutate(data = map(data, function(df1) mutate(df1, data = map(data, test))))
    

    为了验证这是否有效,我们再次提取上述所需信息:

    map(x2_new$data, ~ .x$data) 
    
    
    # [[1]]
    # [[1]][[1]]
    # # A tibble: 4 x 3
    #    cost type  increa
    #   <dbl> <chr>  <dbl>
    # 1    21 a         36
    # 2    30 b         45
    # 3    44 c         59
    # 4   100 d        115
    # 
    # 
    # [[2]]
    # [[2]][[1]]
    # # A tibble: 4 x 3
    #    cost type  increa
    #   <dbl> <chr>  <dbl>
    # 1    21 a         36
    # 2    30 b         45
    # 3    44 c         59
    # 4   100 d        115
    #
    # ...
    

    Third solution - breaks structure but keep information
    这是我最喜欢的解决方案,因为它将数据转换为整洁的格式并保留所有信息:

    x2 %>% 
      unnest(data) %>% 
      unnest(data) %>% 
      mutate(inc = cost + 15)
    
    # A tibble: 16 x 5
    #    scene client   cost type    inc
    #    <int> <fct>   <dbl> <chr> <dbl>
    #  1     1 factory    21 a        36
    #  2     1 factory    30 b        45
    #  3     1 factory    44 c        59
    #  4     1 factory   100 d       115
    #  5     2 factory    21 a        36
    #  6     2 factory    30 b        45
    #  7     2 factory    44 c        59
    #  8     2 factory   100 d       115
    #  9     3 factory    21 a        36
    # 10     3 factory    30 b        45
    # 11     3 factory    44 c        59
    # 12     3 factory   100 d       115
    # 13     4 factory    21 a        36
    # 14     4 factory    30 b        45
    # 15     4 factory    44 c        59
    # 16     4 factory   100 d       115
    

    Data

    generic_data <- structure(
      list(client = structure(1L, .Label = "factory", class = "factor"), 
           data = list(structure(list(cost = c(21, 30, 44, 100), 
                                      type = c("a", "b", "c", "d")), 
                                 row.names = c(NA, -4L), 
                                 class = c("tbl_df", "tbl", "data.frame")))), 
      row.names = c(NA, -1L), class = c("tbl_df", "tbl", "data.frame"))
    
    x2 <- structure(
      list(scene = 1:4, 
           data = list(generic_data, generic_data, generic_data, generic_data)), 
      row.names = c(NA, -4L), class = c("tbl_df", "tbl", "data.frame"))
    

相关问题