【问题标题】:Create a dummy to indicating presence of string fragment in any of multiple variables创建一个虚拟变量以指示多个变量中的任何一个中是否存在字符串片段
【发布时间】:2018-08-01 12:00:01
【问题描述】:
df <- data.frame (address.1.line = c("apartment 5", "25 spring street", "nice house"), address.2.line = c("london", "new york", "apartment 2"), address.3.line = c("", "", "paris"))

我正在尝试创建一个在数据框中返回新列的函数。该列应该是附加到原始数据帧的虚拟变量,指示 3 个地址行变量中的任何一个是否包含字符串(或字符串选择)。

例如,在上面的示例中,我希望 df 有一个名为“Apartment_dummy”的新变量,指示在三个地址行中的任何一个中都存在字符串片段“apartment”---所以它在第 1 行中取 1和 3,第 0 行为零。该函数需要 2 个参数,因此:要创建的新虚拟变量的名称,以及需要在地址变量中检测的相应字符串片段。

我尝试了以下方法。它将返回一个虚拟变量,但不会为新变量提供正确的名称。另外,我觉得必须有一种方法可以一步完成。有任何想法吗?非常感谢!

library(tidyverse)
premises_dummy <- function(varname = NULL, strings = NULL) {
df %<>%    mutate_at(.funs = funs(flagA = str_detect(., strings)), .vars = vars(ends_with(".line"))) %>% 
       mutate(varname = ifelse(rowSums(select(., contains("flagA"))) > 0, 1, 0))
return(df)
}

df <- premises_dummy(varname = 'Apartment_dummy', strings = 'apartment')

【问题讨论】:

    标签: r tidyverse stringr


    【解决方案1】:

    使用tidyr::unitestringr::str_detecttidyverse 选项

    library(tidyverse)
    df %>%
        unite(tmp, remove = F) %>%
        mutate(Apartment_dummy = +str_detect(tmp, "apartment")) %>%
        select(-tmp)
    #    address.1.line address.2.line address.3.line Apartment_dummy
    #1      apartment 5         london                              1
    #2 25 spring street       new york                              0
    #3       nice house    apartment 2          paris               1
    

    【讨论】:

      【解决方案2】:

      一个快速的data.table 解决方案:

      library(data.table)
      dt <- data.table(df)
      search_string <- "apartment"
      dt[like(address.1.line, search_string)| 
         like(address.2.line, search_string)| 
         like(address.3.line, search_string), paste0(search_string,".Dummy") := 1]
      
      dt[is.na(get(paste0(search_string,".Dummy"))), paste0(search_string,".Dummy") := 0]
      

      【讨论】:

      • 非常感谢,但这不是一个函数(我需要应用它来创建一堆基于不同字符串的新列),我更喜欢 tidyverse 解决方案以保持一致性。跨度>
      • 好吧,你可以让列名和搜索字符串动态化。
      • 刚刚更新了答案以使用动态搜索字符串。应该适用于多个搜索词。
      【解决方案3】:

      基础 R 解决方案:

       cols = endsWith(names(df),"line")
       df['Apartment_dummy'] = as.integer(grepl('apartment',do.call(paste,df[cols])))
      

      现在我们可以编写一个函数,它甚至考虑要使用的数据,即数据作为参数。

      premises_dummy=function(varname,strings){
         cols = endsWith(names(df),"line")
         df[varname]= as.integer(grepl(strings,do.call(paste,df[cols])))
         df
       }
       premises_dummy(varname = 'Apartment_dummy', strings = 'apartment')
          address.1.line address.2.line address.3.line Apartment_dummy
      1      apartment 5         london                              1
      2 25 spring street       new york                              0
      3       nice house    apartment 2          paris               1
      

      【讨论】:

      • 这让我非常接近。但在应用程序中,我在 df 中也有其他变量。我怎样才能让它只搜索 3 个地址行变量中是否存在字符串片段,而不是其他变量?
      猜你喜欢
      • 2015-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-13
      • 2016-10-21
      • 2019-03-02
      相关资源
      最近更新 更多