为向量R中的另一个模式查找相应的模式

为向量R中的另一个模式查找相应的模式,r,R,给定这样一个向量: c(“节点1”, “主要”, “运动,提高”, “音乐,提高”, “绘画,提高”, “代理,同意”, “音乐,同意”, “节点2”, “主要”, “音乐,提高”, “绘画,提高”, “节点3”, “主要”, “运动,提高”, “节点4”, “代理”, “音乐,同意”, “运动,同意”, “节点5”, “节点6”, “主要”, “绘画,改进”) 我想将每个“primary”元素下的每个名称及其对应的节点作为单个字符串。对应的节点是“主”元素之前最近的节点名称。例如:对于第一个

给定这样一个向量:

c(“节点1”,
“主要”,
“运动,提高”,
“音乐,提高”,
“绘画,提高”,
“代理,同意”,
“音乐,同意”,
“节点2”,
“主要”,
“音乐,提高”,
“绘画,提高”,
“节点3”,
“主要”,
“运动,提高”,
“节点4”,
“代理”,
“音乐,同意”,
“运动,同意”,
“节点5”,
“节点6”,
“主要”,
“绘画,改进”)
我想将每个“primary”元素下的每个名称及其对应的节点作为单个字符串。对应的节点是“主”元素之前最近的节点名称。例如:对于第一个节点,即上面向量中的第一个元素(“节点1”),应该有三个输出:“节点1体育”、“节点1音乐”、“节点1绘画”。对于“节点2”,应该有两个:“节点2音乐”,“节点2绘画”。数据比给定的向量大得多,因此不首选索引和手动生成字符串。我最初的想法是用grepl找到每个包含“改进”的元素。某些节点下没有“主节点”,因此不应为其分配字符串。预期产出为:

“节点1运动”
“节点1音乐”
“节点1绘制”
“节点2音乐”
“节点2绘制”
“节点3体育”
“节点6绘制”
源数据

my_nodes <- data.frame(stringsAsFactors = FALSE, 
                       src_vec = c("node 1",
  "primary",
  "sports, improve",
  "music, improve",
  "painting, improve",
  "surrogate, agree",
  "music, agree",
  "node 2", 
  "primary", 
  "music, improve",
  "painting, improve",
  "node 3", 
  "primary",
  "sports, improve",
  "node 4",
  "surrogate",
  "music, agree",
  "sports, agree",
  "node 5",
  "node 6",
  "primary",
  "painting, improve"))

my_nodes在这种情况下,我们可以检查
base R
中子集的
length
Filter
那些
NULL
元素和
stack
将其放入两列
data.frame

stack(Filter(Negate(is.null),
   lapply(split(v1, cumsum(grepl('node', v1))), 
   function(x) {
      x1 <- sub(",.*", "", x[grep('improve', x)])
          if(length(x1) > 0) paste(x[1], x1)
  })))[2:1]
详情:

  • 向量
    ('v1')拆分为向量的
    列表

    split(v1, cumsum(grepl('node', v1)))
    
  • 只要找到“node”元素,
    grepl
    就会返回TRUE,
    cumsum
    将计数增加1,其中TRUE值为(
    TRUE
    ->1和
    FALSE
    ->0)。这可以用作
    split
    ing向量的索引变量

  • 使用
    lappy在
    列表上循环

  • 使用匿名
    lambda
    函数(
    函数(x)
    )时,“x”是
    列表中的向量元素值
    ,获取具有“改进”子字符串的元素,并将子字符串从
    删除到所有其他字符(
    *

    #  ind          values
    #1   1   node 1 sports
    #2   1    node 1 music
    #3   1 node 1 painting
    #4   2    node 2 music
    #5   2 node 2 painting
    #6   3   node 3 sports
    #7   6 node 6 painting
    
    split(v1, cumsum(grepl('node', v1)))
    
    x1 <- sub(",.*", "", x[grep('improve', x)])
    
    v1 <- c("node 1", "primary", "sports, improve", "music, improve", 
    "painting, improve", 
    "surrogate, agree", "music, agree", "node 2", "primary", "music, improve", 
    "painting, improve", "node 3", "primary", "sports, improve", 
    "node 4", "surrogate", "music, agree", "sports, agree", "node 5", 
    "node 6", "primary", "painting, improve")