Regex 基于与其他列匹配的部分字符串在dataframe中创建新列

Regex 基于与其他列匹配的部分字符串在dataframe中创建新列,regex,string,r,match,partial,Regex,String,R,Match,Partial,我有一个数据框,有两列GL和GLDESC,我想根据列GLDESC中的一些数据添加一个名为KIND的第三列 数据帧如下所示: GL GLDESC 1 515100 Payroll-Indir Salary Labor 2 515900 Payroll-Indir Compensated Absences 3 532300 Bulk Gas 4 539991

我有一个数据框,有两列
GL
GLDESC
,我想根据列
GLDESC
中的一些数据添加一个名为
KIND
的第三列

数据帧如下所示:

      GL                             GLDESC
1 515100         Payroll-Indir Salary Labor
2 515900 Payroll-Indir Compensated Absences
3 532300                           Bulk Gas
4 539991                     Area Charge In
5 551000        Repairs & Maint-Spare Parts
6 551100                 Supplies-Operating
7 551300                        Consumables
对于数据表的每一行:

  • 如果
    GLDESC
    在字符串中的任何位置包含单词
    Payroll
    ,则我希望
    KIND
    成为
    Payroll
  • 如果
    GLDESC
    在字符串中的任何位置包含单词
    Gas
    ,则我希望
    KIND
    成为
    Materials
  • 在所有其他情况下,我希望
    KIND
    成为
    other

我在stackoverflow上查找了类似的示例,但没有找到任何,也在
R
中查找了开关上的假人,grep,应用和正则表达式,尝试只匹配
GLDESC
列的一部分,然后用帐户类型填充
KIND
列,但无法使其工作。

由于只有两个条件,因此可以使用嵌套的
ifelse

#random data; it wasn't easy to copy-paste yours  
DF <- data.frame(GL = sample(10), GLDESC = paste(sample(letters, 10), 
  c("gas", "payroll12", "GaSer", "asdf", "qweaa", "PayROll-12", 
     "asdfg", "GAS--2", "fghfgh", "qweee"), sample(letters, 10), sep = " "))

DF$KIND <- ifelse(grepl("gas", DF$GLDESC, ignore.case = T), "Materials", 
         ifelse(grepl("payroll", DF$GLDESC, ignore.case = T), "Payroll", "Other"))

DF
#   GL         GLDESC      KIND
#1   8        e gas l Materials
#2   1  c payroll12 y   Payroll
#3  10      m GaSer v Materials
#4   6       t asdf n     Other
#5   2      w qweaa t     Other
#6   4 r PayROll-12 q   Payroll
#7   9      n asdfg a     Other
#8   5     d GAS--2 w Materials
#9   7     s fghfgh e     Other
#10  3      g qweee k     Other

非常感谢。这正是我需要的,DHi!谢谢分享这个正则表达式,它非常有用。如果我们要定义除
kind
之外的第二个变量,即我希望在新变量
new
中用
xyz
替换另一个字符串
labor
,那么我们必须为每个这样的新变量单独运行正则表达式。此外,您没有在最新的迭代函数中定义
kind
。谢谢@ManasiShah:你的意思是类似于
DF$new=ff(DF$GLDESC,“人工”,“xyz”,“其他”,ignore.case=TRUE)
?最后的函数(
ff
)是一个更通用的函数,其结果可作为第二步用于分配回“data.frame”。还是我没有领会你的意思?
ff = function(x, patterns, replacements = patterns, fill = NA, ...)
{
    stopifnot(length(patterns) == length(replacements))

    ans = rep_len(as.character(fill), length(x))    
    empty = seq_along(x)

    for(i in seq_along(patterns)) {
        greps = grepl(patterns[[i]], x[empty], ...)
        ans[empty[greps]] = replacements[[i]]  
        empty = empty[!greps]
    }

    return(ans)
}

ff(DF$GLDESC, c("gas", "payroll"), c("Materials", "Payroll"), "Other", ignore.case = TRUE)
# [1] "Materials" "Payroll"   "Materials" "Other"     "Other"     "Payroll"   "Other"     "Materials" "Other"     "Other"

ff(c("pat1a pat2", "pat1a pat1b", "pat3", "pat4"), 
   c("pat1a|pat1b", "pat2", "pat3"), 
   c("1", "2", "3"), fill = "empty")
#[1] "1"     "1"     "3"     "empty"

ff(c("pat1a pat2", "pat1a pat1b", "pat3", "pat4"), 
   c("pat2", "pat1a|pat1b", "pat3"), 
   c("2", "1", "3"), fill = "empty")
#[1] "2"     "1"     "3"     "empty"