【问题标题】:How to access the name of a list before mapping it?如何在映射之前访问列表的名称?
【发布时间】:2020-01-20 11:27:11
【问题描述】:

我正在尝试将一个数据帧拆分为较小的数据帧,如果它们满足函数的命名条件,则将它们映射到某个函数。我尝试了很多方法,用 purrr map 直接使用 map_if 进行拆分,但并不幸运所以我现在使用splitlapply

所以我将编写我现在陷入困境的代码。

x <- split(mtcars , mtcars$cyl)

lapply(x, function(x){
  print(names(x))
  })

我期望得到的是:

4
6
8

我得到的是

 [1] "mpg"  "cyl"  "disp" "hp"   "drat" "wt"   "qsec" "vs"   "am"   "gear" "carb"
 [1] "mpg"  "cyl"  "disp" "hp"   "drat" "wt"   "qsec" "vs"   "am"   "gear" "carb"
 [1] "mpg"  "cyl"  "disp" "hp"   "drat" "wt"   "qsec" "vs"   "am"   "gear" "carb"
$`4`
 [1] "mpg"  "cyl"  "disp" "hp"   "drat" "wt"   "qsec" "vs"   "am"   "gear" "carb"

$`6`
 [1] "mpg"  "cyl"  "disp" "hp"   "drat" "wt"   "qsec" "vs"   "am"   "gear" "carb"

$`8`
 [1] "mpg"  "cyl"  "disp" "hp"   "drat" "wt"   "qsec" "vs"   "am"   "gear" "carb"

看来是直接进入item,没有办法从apply里面提取item的父名。

关于您如何做的任何建议会有帮助?

更新

这是我想在虚拟代码中做的事情

x <- split(mtcars , mtcars$cyl)

lapply(x, function(x){
  if(names(x) == 4){
somefunction(x)
}
  })

【问题讨论】:

    标签: r mapping purrr


    【解决方案1】:

    Lapply 遍历列表的每个元素,然后应用函数,这意味着 names 被应用到单个数据框并因此输出列名。

    但我的问题是,为什么要访问这些名称?在这种情况下,名称无论如何都对应于“cyl”列,因此您可以使您的函数仅依赖于该列的值。

    【讨论】:

    • 请检查更新。我想根据这个类别名称传递给另一个函数。并非所有项目都将传递给同一个函数。
    • @Omar113 但是为什么不能根据与 df 名称相同的列值传递函数? x$'4' 的 cyl 中的所有行都是 4,因此测试它比访问数据框名称更容易。
    • 我应该在 apply 函数本身中这样做还是不需要拆分然后 lapply 并且最好循环?
    • @Omar113 这实际上取决于您的数据集、您要拆分的原因以及您要应用的功能。您需要添加更多信息。因为如果您只想根据示例中的“cyl”值创建一个具有不同功能的新列,为什么还要拆分?为什么不在大 df 中使用条件函数?您必须更具体地了解您的问题和数据集。
    【解决方案2】:

    OP 方法的可能修复:

    somefunction <- function(df) dplyr::summarise_all(df, mean)
    
    some_naming_condition <- function(group) group == "4"
    
    lapply(
      names(x),
      function(name) {
        if (some_naming_condition(name)) {
          somefunction(x[[name]])
        } else {
          x[[name]]
        }
      }
    )
    #> [[1]]
    #>        mpg cyl     disp       hp     drat       wt     qsec        vs
    #> 1 26.66364   4 105.1364 82.63636 4.070909 2.285727 19.13727 0.9090909
    #>          am     gear     carb
    #> 1 0.7272727 4.090909 1.545455
    #> 
    #> [[2]]
    #>                 mpg cyl  disp  hp drat    wt  qsec vs am gear carb
    #> Mazda RX4      21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
    #> Mazda RX4 Wag  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
    #> Hornet 4 Drive 21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
    #> Valiant        18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
    #> Merc 280       19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
    #> Merc 280C      17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
    #> Ferrari Dino   19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
    #> 
    #> [[3]]
    #>                      mpg cyl  disp  hp drat    wt  qsec vs am gear carb
    #> Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
    #> Duster 360          14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
    #> ...
    

    或等效:

    Map(function(name, sub_df) {
      if (some_naming_condition(name)) {
        somefunction(sub_df)
      } else {
        sub_df
      }
    }, names(x), x)
    

    另一种建议的方法:

    library(tidyr)
    library(purrr)
    library(dplyr)
    
    mtcars %>% 
      nest(-cyl) %>% 
      mutate(data = modify_at(data, which(some_naming_condition(cyl)), 
                              somefunction)) %>% 
      unnest()
    #> # A tibble: 22 x 11
    #>      cyl   mpg  disp    hp  drat    wt  qsec    vs    am  gear  carb
    #>    <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
    #>  1     6  21    160  110    3.9   2.62  16.5 0     1      4     4   
    #>  2     6  21    160  110    3.9   2.88  17.0 0     1      4     4   
    #>  3     6  21.4  258  110    3.08  3.22  19.4 1     0      3     1   
    #>  4     6  18.1  225  105    2.76  3.46  20.2 1     0      3     1   
    #>  5     6  19.2  168. 123    3.92  3.44  18.3 1     0      4     4   
    #>  6     6  17.8  168. 123    3.92  3.44  18.9 1     0      4     4   
    #>  7     6  19.7  145  175    3.62  2.77  15.5 0     1      5     6   
    #>  8     4  26.7  105.  82.6  4.07  2.29  19.1 0.909 0.727  4.09  1.55
    #>  9     8  18.7  360  175    3.15  3.44  17.0 0     0      3     2   
    #> 10     8  14.3  360  245    3.21  3.57  15.8 0     0      3     4   
    #> # … with 12 more rows
    

    【讨论】:

      【解决方案3】:

      使用group_bygroup_split 可以工作。下面是一个使用 summary 作为任意函数的示例,以应用于具有 cylindars == 6 的子集。

      cyl_groups <- mtcars %>% group_by(cyl)
      cyl_groups %>% group_split %>% map_if(group_keys(cyl_groups) == 6, summary)
      #> [[1]]
      #> # A tibble: 11 x 11
      #>      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
      #>    <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
      #>  1  22.8     4 108      93  3.85  2.32  18.6     1     1     4     1
      #>  2  24.4     4 147.     62  3.69  3.19  20       1     0     4     2
      #>  3  22.8     4 141.     95  3.92  3.15  22.9     1     0     4     2
      #>  4  32.4     4  78.7    66  4.08  2.2   19.5     1     1     4     1
      #>  5  30.4     4  75.7    52  4.93  1.62  18.5     1     1     4     2
      #>  6  33.9     4  71.1    65  4.22  1.84  19.9     1     1     4     1
      #>  7  21.5     4 120.     97  3.7   2.46  20.0     1     0     3     1
      #>  8  27.3     4  79      66  4.08  1.94  18.9     1     1     4     1
      #>  9  26       4 120.     91  4.43  2.14  16.7     0     1     5     2
      #> 10  30.4     4  95.1   113  3.77  1.51  16.9     1     1     5     2
      #> 11  21.4     4 121     109  4.11  2.78  18.6     1     1     4     2
      #> 
      #> [[2]]
      #>       mpg             cyl         disp             hp       
      #>  Min.   :17.80   Min.   :6   Min.   :145.0   Min.   :105.0  
      #>  1st Qu.:18.65   1st Qu.:6   1st Qu.:160.0   1st Qu.:110.0  
      #>  Median :19.70   Median :6   Median :167.6   Median :110.0  
      #>  Mean   :19.74   Mean   :6   Mean   :183.3   Mean   :122.3  
      #>  3rd Qu.:21.00   3rd Qu.:6   3rd Qu.:196.3   3rd Qu.:123.0  
      #>  Max.   :21.40   Max.   :6   Max.   :258.0   Max.   :175.0  
      #>       drat             wt             qsec             vs        
      #>  Min.   :2.760   Min.   :2.620   Min.   :15.50   Min.   :0.0000  
      #>  1st Qu.:3.350   1st Qu.:2.822   1st Qu.:16.74   1st Qu.:0.0000  
      #>  Median :3.900   Median :3.215   Median :18.30   Median :1.0000  
      #>  Mean   :3.586   Mean   :3.117   Mean   :17.98   Mean   :0.5714  
      #>  3rd Qu.:3.910   3rd Qu.:3.440   3rd Qu.:19.17   3rd Qu.:1.0000  
      #>  Max.   :3.920   Max.   :3.460   Max.   :20.22   Max.   :1.0000  
      #>        am              gear            carb      
      #>  Min.   :0.0000   Min.   :3.000   Min.   :1.000  
      #>  1st Qu.:0.0000   1st Qu.:3.500   1st Qu.:2.500  
      #>  Median :0.0000   Median :4.000   Median :4.000  
      #>  Mean   :0.4286   Mean   :3.857   Mean   :3.429  
      #>  3rd Qu.:1.0000   3rd Qu.:4.000   3rd Qu.:4.000  
      #>  Max.   :1.0000   Max.   :5.000   Max.   :6.000  
      #> 
      #> [[3]]
      #> # A tibble: 14 x 11
      #>      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
      #>    <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
      #>  1  18.7     8  360    175  3.15  3.44  17.0     0     0     3     2
      #>  2  14.3     8  360    245  3.21  3.57  15.8     0     0     3     4
      #>  3  16.4     8  276.   180  3.07  4.07  17.4     0     0     3     3
      #>  4  17.3     8  276.   180  3.07  3.73  17.6     0     0     3     3
      #>  5  15.2     8  276.   180  3.07  3.78  18       0     0     3     3
      #>  6  10.4     8  472    205  2.93  5.25  18.0     0     0     3     4
      #>  7  10.4     8  460    215  3     5.42  17.8     0     0     3     4
      #>  8  14.7     8  440    230  3.23  5.34  17.4     0     0     3     4
      #>  9  15.5     8  318    150  2.76  3.52  16.9     0     0     3     2
      #> 10  15.2     8  304    150  3.15  3.44  17.3     0     0     3     2
      #> 11  13.3     8  350    245  3.73  3.84  15.4     0     0     3     4
      #> 12  19.2     8  400    175  3.08  3.84  17.0     0     0     3     2
      #> 13  15.8     8  351    264  4.22  3.17  14.5     0     1     5     4
      #> 14  15       8  301    335  3.54  3.57  14.6     0     1     5     8
      

      如果您只想保持与您的条件相匹配的小标题,另一种选择是

      mtcars %>% split(.$cyl) %>% keep(names(.) == 6) %>% map(somefunction())
      

      【讨论】:

        猜你喜欢
        • 2015-06-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-05
        • 2018-06-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多