使用字符向量构建一个新的数据框,其中包含从该向量中找到字符串的行

Use a character vector to build a new dataframe containing rows in which strings from that vector are found

我想使用字符向量 query_list 和 return 数据帧 query_output 查询 database。在这个两列输出数据框中,每一行对应于查询向量中的一个字符串。输出数据框中的两列中的第一列(称为 term)命名此字符串,第二列(称为 enzyme)列出了 database 中找到查询字符串的所有行,由数据库中的列 enzyme 定义)。

我的查询和数据库如下所示:

query_list <- c("term(A)", "term(B)", "term(C)", "term(D15)")
database <- data.frame(enzyme = c("A1", "B1", "C1", "D1", "E1")
                       ,term = c("term(A);term(K);term(Y);term(G);term(F);"
                                 ,"term(A);term(K);term(Y);term(G);term(F);"
                                 ,"term(H);term(K);term(Y);term(C);term(F);"
                                 ,"term(H);term(B);term(Y);term(C);term(F);"
                                 ,"term(H);term(K);term(D15);term(G);term(F);"))

数据库如下所示:

  enzyme                                       term
1     A1   term(A);term(K);term(Y);term(G);term(F);
2     B1   term(A);term(K);term(Y);term(G);term(F);
3     C1   term(H);term(K);term(Y);term(C);term(F);
4     D1   term(H);term(B);term(Y);term(C);term(F);
5     E1   term(H);term(K);term(D15);term(G);term(F);

结果数据帧query_output:

> query_output 
       term  enzyme
1   term(A)  A1, B1
2   term(B)      D1
3   term(C)  C1, D1
4 term(D15)      E1

最理想的是,解决方案是可管道化的,而不是循环(尽管任何东西都会受到赞赏)。我不说我尝试过的东西,因为我真的不知道如何用简洁的方式去做。

使用 tidyr 包中的 separate_rows(),您可以分隔 term 中的值。然后,只需按 query_list 过滤,按 term 分组并使用 paste0(..., collapse=';') 折叠同一行中每个 term 的所有值。

database %>% 
  tidyr::separate_rows(term,sep=";") %>% 
  filter(term %in% query_list) %>%
  group_by(term) %>% 
  summarise(enzyme = paste0(enzyme,collapse=', '))

输出:

# A tibble: 4 x 2
  term      enzyme
  <chr>     <chr> 
1 term(A)   A1, B1 
2 term(B)   D1    
3 term(C)   C1, D1 
4 term(D15) E1   

您可以将数据库转换为您想要的格式

library(dplyr)
library(tidyr)

transformed_database <- database %>%
  separate_rows(term, sep = ';') %>%
  filter(term != '') %>%
  group_by(term) %>%
  summarise(enzyme = paste0(enzyme, collapse = ', '))

transformed_database
#> # A tibble: 9 × 2
#>   term      enzyme            
#>   <chr>     <chr>             
#> 1 term(A)   A1, B1            
#> 2 term(B)   D1                
#> 3 term(C)   C1, D1            
#> 4 term(D15) E1                
#> 5 term(F)   A1, B1, C1, D1, E1
#> 6 term(G)   A1, B1, E1        
#> 7 term(H)   C1, D1, E1        
#> 8 term(K)   A1, B1, C1, E1    
#> 9 term(Y)   A1, B1, C1, D1

那么,查询就这么简单

transformed_database %>%
  filter(term %in% query_list)

#> # A tibble: 4 × 2
#>   term      enzyme
#>   <chr>     <chr> 
#> 1 term(A)   A1, B1
#> 2 term(B)   D1    
#> 3 term(C)   C1, D1
#> 4 term(D15) E1

我们可以遍历 base R 中的 query_list,并使用 tibble 中的 enflame 使其成为数据帧。

library(tibble)

enframe(sapply(query_list, function(x)
  paste(database[grepl(x, strsplit(database$term, ";"), fixed = T), 1], collapse = ", ")),
  name = "term",
  value = "enzyme")

# A tibble: 4 × 2
  term      enzyme
  <chr>     <chr> 
1 term(A)   A1, B1
2 term(B)   D1    
3 term(C)   C1, D1
4 term(D15) E1     

我的解决方案是:

database %>% 
  separate_rows(term, sep = ";") %>% 
  filter(term != "") %>%
  filter(term %in% query_list) %>% 
  print() %>% 
  group_by(term) %>% 
  summarise(enzyme = str_c(enzyme, collapse = ", ")) %>% 
  ungroup()

结果是

# A tibble: 4 × 2
  term      enzyme
  <chr>     <chr> 
1 term(A)   A1, B1
2 term(B)   D1    
3 term(C)   C1, D1
4 term(D15) E1

试试这个:

library(tidyr)
database %>%
  mutate(term = sub(";$", "", term)) %>%
  separate_rows(term, sep = ";") %>%
  filter(term %in% query_list) %>%
  group_by(term) %>%
  summarise(enzyme = toString(enzyme))
# A tibble: 4 × 2
  term      enzyme
  <chr>     <chr> 
1 term(A)   A1, B1
2 term(B)   D1    
3 term(C)   C1, D1
4 term(D15) E1