简体   繁体   English

基于行或列匹配的多个数据框的子集列表

[英]subset list of multiple dataframe based on either row or column match

library(tidyverse)
library(dplyr)

list of data frames where some have matches to the vector and some don't数据框列表,其中有些与向量匹配,有些不匹配

lsdf <- list(
  list1 = head(mtcars),
  list2 = as.data.frame(t(head(mtcars))) %>%
    rownames_to_column(., var = "ID"),
  list3 = head(starwars)
)

the vector of names that match to some dataframe与某个数据框匹配的名称向量

vec <- c("mpg", "wt", "am")

If I have to manually do it step by step this would be like this.如果我必须手动一步一步地做这将是这样的。

df1 <- lsdf$list1 %>% select(vec) # column-name matches
df2 <- lsdf$list2 %>% filter(ID %in% vec) # values in ID columns matches
df3 <- lsdf$list3 # No match found

out_lsdf <- list(
  df1 = df1,
  df2 = df2,
  df3 = df3
)

Is there a better and faster way to get the output desired below ?有没有更好更快的方法来获得下面所需的输出?

out_lsdf
#> $df1
#>                    mpg    wt am
#> Mazda RX4         21.0 2.620  1
#> Mazda RX4 Wag     21.0 2.875  1
#> Datsun 710        22.8 2.320  1
#> Hornet 4 Drive    21.4 3.215  0
#> Hornet Sportabout 18.7 3.440  0
#> Valiant           18.1 3.460  0
#> 
#> $df2
#>    ID Mazda RX4 Mazda RX4 Wag Datsun 710 Hornet 4 Drive Hornet Sportabout
#> 1 mpg     21.00        21.000      22.80         21.400             18.70
#> 2  wt      2.62         2.875       2.32          3.215              3.44
#> 3  am      1.00         1.000       1.00          0.000              0.00
#>   Valiant
#> 1   18.10
#> 2    3.46
#> 3    0.00
#> 
#> $df3
#> # A tibble: 6 x 13
#>   name  height  mass hair_color skin_color eye_color birth_year gender homeworld
#>   <chr>  <int> <dbl> <chr>      <chr>      <chr>          <dbl> <chr>  <chr>    
#> 1 Luke~    172    77 blond      fair       blue            19   male   Tatooine 
#> 2 C-3PO    167    75 <NA>       gold       yellow         112   <NA>   Tatooine 
#> 3 R2-D2     96    32 <NA>       white, bl~ red             33   <NA>   Naboo    
#> 4 Dart~    202   136 none       white      yellow          41.9 male   Tatooine 
#> 5 Leia~    150    49 brown      light      brown           19   female Alderaan 
#> 6 Owen~    178   120 brown, gr~ light      blue            52   male   Tatooine 
#> # ... with 4 more variables: species <chr>, films <list>, vehicles <list>,
#> #   starships <list>

Created on 2020-02-07 by the reprex package (v0.3.0)reprex 包(v0.3.0) 于 2020 年 2 月 7 日创建

We can do this with a condition to check我们可以用一个条件来检查

library(purrr)
library(dplyr)
map(lsdf, ~ {nm1 <- names(.x)
      if("ID" %in% nm1)  .x %>%
                   filter(ID %in% vec) else if(any(nm1 %in% vec)) 
       .x %>% select(intersect(nm1, vec))
 else .x
 })

We could also call the if/else conditions within select/filter我们也可以在select/filter调用if/else条件

map(lsdf, ~ .x %>% 
                select(if(any(names(.) %in% vec)) 
                   intersect(names(.), vec) else everything()) %>% 
                filter(if('ID' %in% names(.)) ID %in% vec else TRUE))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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