根据 R 列中的部分匹配创建新变量

Create new variable based on partial matching in column R

我正在尝试根据类似于以下数据的内容在 data.frame 中创建一个新变量:

df <- structure(list(id = c(123L, 123L, 332L, 332L, 332L, 100L, 100L, 
113L, 113L, 113L, 113L, 551L, 551L), icpc = c("D95", "F85", "A01", 
"A04", "K20", "B10", "A04", "T08", "P28", "D95", "A04", "B12", 
"D95"), icpc2 = c("F15", "", "", "", "", "", "", "", "", "A01", 
"", "A01", ""), reg.date = c("19JUN2015", "15AUG2016", "16MAR2010", 
"20JAN2018", "20FEB2017", "01JUN2017", "11JAN2008", "18MAR2018", 
"19JAN2017", "16JAN2013", "01MAY2009", "03APR2011", "09MAY2015"
)), class = "data.frame", row.names = c(NA, -13L))

我已经为新列 condit 使用以下代码进行管理:

library(data.table)

cond1 <- c("D95", "A01")
setDT(df)[, condit := ifelse(any(icpc %in% cond1 | icpc2 %in% cond1), "yes","no"), by=id]
df

但是,我正在处理一个大数据集 (>4000 万) 并且还想根据 icpcicpc2 中的字母进行分类.

我的目标是添加一个新列,它给出 yesno 到字母 A(因此,A01A04A50 等)在 icpcicpc2 列中。我还希望具有相同 id 的所有列在新列 condit2 中具有 yes

我正在尝试以下操作:

df2 <- setDT(df)[, condit2 := ifelse
                            (any(icpc %in% pmatch("K", df) | icpc2 %in% pmatch("K", df)), "yes","no"), by = PATNR]
head(df2)

这一直保持在 运行 永远...(我猜,df 太面包了,如果应该是 df$icpcdf$icpc2?)

比以下检查 pmatch 是否合适:

condit2 <- pmatch("K")

然后看了一些完全不同的东西:

library(sqldf)
condit2 <- sqldf("df$icpc | df$icpc2, '%K%'")

这将导致以下数据框:

    id  icpc icpc2 reg.date    condit2
 1: 123  D95   F15 19JUN2015    no
 2: 123  F85       15AUG2016    no
 3: 332  A01       16MAR2010    yes
 4: 332  A04       20JAN2018    yes
 5: 332  K20       20FEB2017    yes
 6: 100  B10       01JUN2017    yes
 7: 100  A04       11JAN2008    yes
 8: 113  T08       18MAR2018    yes
 9: 113  P28       19JAN2017    yes
10: 113  D95   A01 16JAN2013    yes
11: 113  A04       01MAY2009    yes
12: 551  B12   A01 03APR2011    yes
13: 551  D95       09MAY2015    yes

谁能给个提示?谢谢!!

使用 dplyr 这可以通过以下方法完成: group_by(id)paste 将感兴趣的两列放在一起,并使用 sumgrepl.[=17 检查是否至少有一个 A 出现在连接的字符串中=]

library(dplyr)
df %>% 
  group_by(id) %>% 
  mutate(condit2 = case_when(sum(grep("A", paste(icpc, icpc2))) > 0 ~ "yes",
                             TRUE ~ "no")) %>% 
  ungroup()


      id icpc  icpc2 reg.date  condit2
   <int> <chr> <chr> <chr>     <chr>  
 1   123 D95   "F15" 19JUN2015 no     
 2   123 F85   ""    15AUG2016 no     
 3   332 A01   ""    16MAR2010 yes    
 4   332 A04   ""    20JAN2018 yes    
 5   332 K20   ""    20FEB2017 yes    
 6   100 B10   ""    01JUN2017 yes    
 7   100 A04   ""    11JAN2008 yes    
 8   113 T08   ""    18MAR2018 yes    
 9   113 P28   ""    19JAN2017 yes    
10   113 D95   "A01" 16JAN2013 yes    
11   113 A04   ""    01MAY2009 yes    
12   551 B12   "A01" 03APR2011 yes    
13   551 D95   ""    09MAY2015 yes    
setDT(df)

to_check <- 'A'

df[, condit2 := fifelse(any(grepl(to_check, icpc) | grepl(to_check, icpc2)),
                        'yes', 'no'), 
   by = id]

df
#      id icpc icpc2  reg.date condit2
#  1: 123  D95   F15 19JUN2015      no
#  2: 123  F85       15AUG2016      no
#  3: 332  A01       16MAR2010     yes
#  4: 332  A04       20JAN2018     yes
#  5: 332  K20       20FEB2017     yes
#  6: 100  B10       01JUN2017     yes
#  7: 100  A04       11JAN2008     yes
#  8: 113  T08       18MAR2018     yes
#  9: 113  P28       19JAN2017     yes
# 10: 113  D95   A01 16JAN2013     yes
# 11: 113  A04       01MAY2009     yes
# 12: 551  B12   A01 03APR2011     yes
# 13: 551  D95       09MAY2015     yes

如果您有很多列而不是只有两列 icpcicpc2,并且不想为每个列都输入 grepl 代码,这里是.SDcols 的版本给出了相同的结果。

df[, condit2 := fifelse(any(Reduce('|', lapply(.SD, grepl, patt = to_check))),
                        'yes', 'no'), 
   by = id, .SDcols = patterns('icpc')]