创建一个虚拟变量以指示是否存在多个变量中的字符串片段

时间:2018-08-01 12:00:02

标签: r tidyverse stringr

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')

3 个答案:

答案 0 :(得分:1)

快速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]

答案 1 :(得分:1)

使用tidyversetidyr::unite的{​​{1}}选项

stringr::str_detect

答案 2 :(得分:0)

基本的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