R

时间:2017-10-24 11:27:33

标签: r string grep match strsplit

我有一个大数据按两个标识符(组和ID)分组,Initial列显示在初始时间段,Post列显示在初始时间段后出现的元素。一个工作的例子如下:

SampleDF<-data.frame(Group=c(0,0,1),ID=c(2,2,3),
Initial=c('F28D,G06F','F24J ,'G01N'), 
Post=c('G06F','H02G','F23C,H02G,G01N'))

我希望比较InitialPost中每个Group/ID组合的元素,以找出元素何时匹配,何时只存在新元素,以及何时存在新元素和新元素存在。理想情况下,我希望最终得到一个新的Type变量,其输出如下:

SampleDF<-cbind(SampleDF, 'Type'=rbind(0,1,2))

其中(相对于Initial0表示Post中没有新元素,1表示只有新元素在Post中,2表示Post中有预先存在的元素和新元素。

2 个答案:

答案 0 :(得分:1)

您的情况很复杂,因为patternvector在使用agrepl进行字符串匹配时会有所不同。所以,在这里,我提出了一个非常棘手的解决方案,但是做得很好。

element_counter = list()
for (i in 1:length(SampleDF$Initial)) {
  if (length(strsplit(as.character(SampleDF$Initial[i]), ",")[[1]]) > 1) {
    element_counter[[i]] <- length(as.character(SampleDF$Post[i])) - sum(agrepl(as.character(SampleDF$Post[i]),strsplit(as.character(SampleDF$Initial[i]), ",")[[1]]))
  }   else { 
    element_counter[[i]] <- length(strsplit(as.character(SampleDF$Post[i]), ",")[[1]]) - sum(agrepl(SampleDF$Initial[i], strsplit(as.character(SampleDF$Post[i]), ",")[[1]]))
  }
}

SampleDF$Type <- unlist(element_counter) 


## SampleDF
#   Group  ID   Initial             Post  Type
#1     0   2  F28D,G06F             G06F    0
#2     0   2       F24J             H02G    1
#3     1   3       G01N   F23C,H02G,G01N    2

答案 1 :(得分:1)

我将流程拆分为两个步骤,查找具有新值的行,然后查找仅使用 新值的行。将这两个逻辑向量一起添加将创建类型。唯一需要注意的是,类型定义与您的问题定义略有不同。 0表示没有新措施,1表示有新的和预先存在的措施,2表示只有预先存在的措施。

# This approach needs character columns not strings, so stringsAsFactors = FALSE
SampleDF<-data.frame(Group=c(0,0,1),ID=c(2,2,3),
                     Initial=c('F28D,G06F','F24J' ,'G01N'), 
                               Post=c('G06F','H02G','F23C,H02G,G01N'),
                     stringsAsFactors = FALSE)

# Identify rows where there are new occurrences in Post that are not present in Initial
SampleDF$anyNewOccurrences <- 
  mapply(FUN = function(pattern, x){
    any(!grepl(pattern, x))}, 
    pattern = gsub("," , "|", SampleDF$Initial), 
    x = strsplit(SampleDF$Post, ","))

# Identify rows where there are only new occurences (no repeated values from Initial)
SampleDF$onlyNewOccurrences <- 
  mapply(FUN = function(pattern, x){
    all(!grepl(pattern, x))}, 
    pattern = gsub("," , "|", SampleDF$Initial), 
    x = strsplit(SampleDF$Post, ","))

# Add the two value to gether to create a type code
SampleDF$Type <- SampleDF$onlyNewOccurrences + SampleDF$anyNewOccurrences