【问题标题】:Why do I need to index my data frame to map() after doing map(str_match_all())?为什么我需要在执行 map(str_match_all()) 之后将我的数据框索引到 map()?
【发布时间】:2017-09-13 23:52:20
【问题描述】:

我正在尝试解析包含字符串以提取最大值(数字)的数据框,但遇到了一些麻烦。

如果我从这样的小标题开始:

tester <- tibble("phyloP46way_primate" = c(".{9}", "0.055{1}0.064{3}", "0.225{1}", "0.271{1}", "-0.706{1}-0.708{1}0.248{3}0.298{3}"))

然后使用map()modify() 应用str_match_all() 从每个字符向量中挑选出值,我得到一个带有5 个观察值(每个字符矩阵列表)的小标题(modify())由对 str_match_all() 的 5 次调用返回)(或包含 5 个字符矩阵列表的 1 列表(对于 map())。

regex ≤- "(?:(?:-?\\d+\\.?\\d+?)|\\.)(?=(?:\\{\\d+\\}|;|$))"

> str(foo_tbl<- tester %>% modify(str_match_all, pattern = regex))
Classes 'tbl_df', 'tbl' and 'data.frame':    5 obs. of  1 variable:
 $ phyloP46way_primate:List of 5
  ..$ : chr [1, 1] "."
  ..$ : chr [1:2, 1] "0.055" "0.064"
  ..$ : chr [1, 1] "0.225"
  ..$ : chr [1, 1] "0.271"
  ..$ : chr [1:4, 1] "-0.706" "-0.708" "0.248" "0.298"

> str(foo_list<- tester %>% map(str_match_all, pattern = regex))
List of 1
 $ phyloP46way_primate:List of 5
  ..$ : chr [1, 1] "."
  ..$ : chr [1:2, 1] "0.055" "0.064"
  ..$ : chr [1, 1] "0.225"
  ..$ : chr [1, 1] "0.271"
  ..$ : chr [1:4, 1] "-0.706" "-0.708" "0.248" "0.298"

现在,我想要做的是对这些“行”中的每一行应用一个函数。但是当我尝试映射时,它似乎只是将它们全部连接到一个向量中,并且只从整个批次中选择单个最大值,而不是一个/行:

> map(foo_tbl, function(x) list_to_max(x))
$phyloP46way_primate
$phyloP46way_primate[[1]]
[1] "0.298"

除非我在foo_tbl[[1]]而不是foo_tbl上做一些奇怪的索引和映射:

map(foo_tbl[[1]], function(x) list_to_max(x)) %>% unlist()
[1] "."     "0.064" "0.225" "0.271" "0.298"

我认为我的list_to_max() 一定是在做意想不到的事情,因为这些行为符合我的预期:

> invisible(map(foo_tbl, function(x) print(paste0("x is: ", x))))
[1] "x is: ."                                              
[2] "x is: c(\"0.055\", \"0.064\")"                        
[3] "x is: 0.225"                                          
[4] "x is: 0.271"                                          
[5] "x is: c(\"-0.706\", \"-0.708\", \"0.248\", \"0.298\")"
> invisible(modify(foo_tbl, function(x) print(paste0("x is: ", x))))
[1] "x is: ."                                              
[2] "x is: c(\"0.055\", \"0.064\")"                        
[3] "x is: 0.225"                                          
[4] "x is: 0.271"                                          
[5] "x is: c(\"-0.706\", \"-0.708\", \"0.248\", \"0.298\")"

这是我的功能:

list_to_max <- function(character_vector) {
  numbers <- suppressWarnings(as.numeric(character_vector))
  if (all(is.na(numbers))) {
    return(".")
    } else {
      numbers %>% max(., na.rm = TRUE) %>% toString()
    }
}

【问题讨论】:

    标签: r dplyr tidyverse stringr purrr


    【解决方案1】:

    toString 会将所有内容强制转换为逗号分隔的字符串,这不是很有用。这是一个将所有内容保留在原始 data.frame 中的工作流程:

    library(tidyverse)
    
    tester <- tibble("phyloP46way_primate" = c(".{9}", "0.055{1}0.064{3}", "0.225{1}", "0.271{1}", "-0.706{1}-0.708{1}0.248{3}0.298{3}"))
    
    tester %>% 
        mutate(p_clean = gsub('\\{.*?\\}', ' ', phyloP46way_primate), 
               p_list = strsplit(p_clean, '\\s+'), 
               p_list = map(p_list, as.numeric), 
               p_max = map_dbl(p_list, max))
    #> # A tibble: 5 x 4
    #>                  phyloP46way_primate                    p_clean    p_list p_max
    #>                                <chr>                      <chr>    <list> <dbl>
    #> 1                               .{9}                         .  <dbl [1]>    NA
    #> 2                   0.055{1}0.064{3}               0.055 0.064  <dbl [2]> 0.064
    #> 3                           0.225{1}                     0.225  <dbl [1]> 0.225
    #> 4                           0.271{1}                     0.271  <dbl [1]> 0.271
    #> 5 -0.706{1}-0.708{1}0.248{3}0.298{3} -0.706 -0.708 0.248 0.298  <dbl [4]> 0.298
    

    【讨论】:

    • 这种方法的一个问题是我的真实数据的某些字段同时包含空值(“.”)和数字,例如“0.55{1}.{3}”。 as.numeric() 转换“。”到 NA,max(c(0.55, NA)) 返回 NA,而不是 0.55。因此,如果有一个空值,变异工作流会以错误的 p_max 结束......我正在迭代它,但希望有更多建议!
    • 首先,NULLNA 在 R 中是不同的东西,所以谈论“null”值会让人感到困惑。实际上,将数据存储为 NANULL 或您用来表示缺失数据的任何字符串或数字更有用。代码方面,您可以在max 中使用na.rm = TRUE,尽管当只有. 时它会返回-Inf,尽管可以将其转换回NA
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-30
    • 1970-01-01
    • 1970-01-01
    • 2017-09-19
    • 1970-01-01
    • 1970-01-01
    • 2020-11-28
    相关资源
    最近更新 更多