【问题标题】:Change a script into a function so that it can be looped. The script uses mutate and str_detect to create a new data frame column将脚本更改为函数,以便可以循环。该脚本使用 mutate 和 str_detect 创建一个新的数据框列
【发布时间】:2019-06-24 16:00:47
【问题描述】:

我有一个大型数据框(462K 行),其中有一个变量列出了药品的通用药品名称内容。有成千上万种不同的仿制药;我对其中大约 100 个感兴趣。有些药物有多种仿制药成分;我需要知道药物中是否含有我感兴趣的任何药物。我创建了一个脚本,该脚本使用 mutate 向数据框添加一个新的逻辑变量,如果其中一种仿制药存在,例如“布洛芬”,则为 TRUE,无论是单独存在还是与使用 str_detect 的其他仿制药结合使用。

我想把这个脚本变成一个函数,这样我就可以在感兴趣的药物列表中循环它,而不是为每种感兴趣的药物复制和编辑脚本。

这是一个有效的脚本,在这种情况下,它将在数据框列 drug_generic_name 中找到字符模式 DICLOFEN,并在数据框中创建一个名为 Diclofenac 的新列:

Drug_Table_Names <- data.frame(mutate(Drug_Table_Names, DRUG_GENERIC_NAME, 
                                  Diclofenac = str_detect 
                                  (Drug_Table_Names$DRUG_GENERIC_NAME,"DICLOFEN", negate = FALSE)))

我相信我想要的函数将有两个参数: 1. mutate 的参数,它将是它将创建的变量的名称,在上面的示例中为双氯芬酸。 2. str_detect 的一个参数,用于检测,即药物的通用名称(或在本例中的一部分),在上面的示例中为 DICLOFEN。

我有一个包含两个变量的两列标题 NSAID_LIST,其中 drug_flag 是新变量的名称,gen_name 是 str_detect 将查找的模式:

# A tibble: 6 x 2
  drug_flag    gen_name    
  <chr>        <chr>       
1 Diclofenac   DICLOFENAC  
2 Fenoprofen   FENOPROFEN  
3 Flurbiprofen FLURBIPROFEN
4 Ibuprofen    IBUPROFEN   
5 Ketoprofen   KETOPROFEN  
6 Naproxen     NAPROXEN    

Classes ‘tbl_df’, ‘tbl’ and 'data.frame':   13 obs. of  2 variables:
 $ drug_flag: chr  "Diclofenac" "Fenoprofen" "Flurbiprofen" "Ibuprofen" ...
 $ gen_name : chr  "DICLOFENAC" "FENOPROFEN" "FLURBIPROFEN" "IBUPROFEN" ...

这是我编写名为 FlagDrugNames 的函数的失败尝试:

FlagDrugNames<-function (drug_flag, gen_name) {Drug_Table_Names <- data.frame(mutate(Drug_Table_Names, DRUG_GENERIC_NAME, 
                                     drug_flag = str_detect 
                                     (Drug_Table_Names$DRUG_GENERIC_NAME,
                                       "gen_name", negate = FALSE)))}

我有两个问题: 首先,该功能不起作用(或者我不知道如何使用它)。当我运行函数并输入参数时:

FlagDrugNames(Flurbiprofen, FLURBIPROFEN)

它不会像脚本那样向数据框添加新列。

第二:我想通过上面显示的 tibble 中的 gen_name 和 drug_flag 值列表来运行这个函数。

我将不胜感激编写函数,然后将 drug_flag 和 gen_name 对传递给函数。

【问题讨论】:

    标签: r tidyr stringr


    【解决方案1】:

    以 mtcars 集为例,这样的事情可能会起作用:

    find_names = function(dat, col1, string1, new_col_name) {
    
        mutate_call = lazyeval::interp(~ str_detect(a,string1), a = as.name(col1))
    
        dat %>% mutate_(.dots = setNames(list(mutate_call), new_col_name))
    
        return(dat)
    
      }
    
    mtcars = find_names(mtcars, 'wt', '2', 'ibuprofen')
    

    然后,您使用 for 循环

    for (i in 1:nrow(dict) { find_names(mtcars,'wt',dict[i,1],dict[i,2]) }
    

    【讨论】:

    • 感谢您的建议。我收到了 find_names 函数的错误消息。 mutate_() 已弃用。请改用 mutate() 'programming' vignette 或 tidyeval book 可以帮助您使用 mutate() 进行编程:tidyeval.tidyverse.org 此警告在每个会话中显示一次。
    • 循环代码给出以下错误:错误:意外'{' in "for (i in 1:nrow(dict) {"> find_names = function(dat, col1, string1, new_col_name) { mutate_call = lazyeval::interp(~ str_detect(a,string1), a = as.name(col1)) dat %>% mutate(.dots = setNames(list(mutate_call), new_col_name)) }
    • 另一个问题:该函数可以创建新变量,但它没有将变量添加到原始数据框中,这是我需要做的。
    • 已修复以将更改分配给数据框
    猜你喜欢
    • 1970-01-01
    • 2021-11-14
    • 2012-08-20
    • 2014-10-18
    • 1970-01-01
    • 1970-01-01
    • 2020-05-23
    • 2015-02-12
    • 1970-01-01
    相关资源
    最近更新 更多