代码之家  ›  专栏  ›  技术社区  ›  Zeus

使用mutate和rowwise返回列表

  •  2
  • Zeus  · 技术社区  · 7 年前

    我试图使用mutate和rowwise返回一个列表,但得到了代码中显示的错误。这些问题 Q1 Q2 rowwise() ,问题是3岁7岁。谢谢

    library(tidyverse)    
    df <-  data.frame(Name=c("a","a","b","b","c"),X=c(1,2,3,4,5), Y=c(2,3,4,2,2))
    
        TestFn <- function(X,Y){
          Z <- list(X*5,Y/2,X+Y,X*2+5*Y)
          return (Z)
        }
    
        #this works
        SingleResult <- TestFn(5,20)
    
        #error - Error in mutate_impl(.data, dots) : incompatible size (4), expecting 1 (the group size) or 1
        dfResult <- df %>% 
          rowwise() %>% 
          mutate(R=TestFn(X,Y))
    
    2 回复  |  直到 7 年前
        1
  •  3
  •   CPak    7 年前

    tidyverse 现在可以嵌套复杂的数据结构

    tidyverse溶液

    df %>%
      mutate(copyX = X, copyY = Y) %>%
      nest(copyX, copyY) %>%
      mutate(data = map(data, ~TestFn(.x$copyX, .x$copyY)))
    

    输出

        Name     X     Y       data
      <fctr> <dbl> <dbl>     <list>
    1      a     1     2 <list [4]>
    2      a     2     3 <list [4]>
    3      b     3     4 <list [4]>
    4      b     4     2 <list [4]>
    5      c     5     2 <list [4]>
    

    如何转换为数据帧?

    由于您的函数返回一个列表,因此我在前面添加了一个附加步骤 unnest

    df %>%
      mutate(copyX = X, copyY = Y) %>%
      nest(copyX, copyY) %>%
      mutate(data = map(data, ~TestFn(.x$copyX, .x$copyY))) %>%
      mutate(data = map(data, ~unlist(.x))) %>%
      unnest(data)
    

         Name     X     Y  data
       <fctr> <dbl> <dbl> <dbl>
     1      a     1     2   5.0
     2      a     1     2   1.0
     3      a     1     2   3.0
     4      a     1     2  12.0
     5      a     2     3  10.0
     6      a     2     3   1.5
     # etc
    
        2
  •  2
  •   akuiper    7 年前

    你的 TestFn

    TestFn <- function(X, Y) list(c(X*5, Y/2, X+Y, X*2+5*Y))
    #                             ^ 
    df %>% rowwise() %>% mutate(R=TestFn(X,Y)) %>% pull(R)
    #[[1]]
    #[1]  5  1  3 12
    
    #[[2]]
    #[1] 10.0  1.5  5.0 19.0
    
    #[[3]]
    #[1] 15  2  7 26
    
    #[[4]]
    #[1] 20  1  6 18
    
    #[[5]]
    #[1] 25  1  7 20
    

    rowwise

    df$R = with(df, data.table::transpose(list(X*5, Y/2, X+Y, X*2+5*Y)))
    df
    #  Name X Y                    R
    #1    a 1 2          5, 1, 3, 12
    #2    a 2 3 10.0, 1.5, 5.0, 19.0
    #3    b 3 4         15, 2, 7, 26
    #4    b 4 2         20, 1, 6, 18
    #5    c 5 2         25, 1, 7, 20
    
    推荐文章