tidyr仅分离最后n个实例

tidyr仅分离最后n个实例,r,tidy,R,Tidy,我在R中有一个data.frame,为了简单起见,它有一列我想分开。 使用tidyr::separate截取的以下示例几乎可以完成此任务: tmp2 <- data.frame( varTreatName = c( "resp_Nadd_belowCanopy", "resp_NPadd_belowCanopy" , "resp_sd_Nadd_belowCanopy", "resp_sd_NPadd_belowCanopy")) tmp2 %>% separate(

我在R中有一个data.frame,为了简单起见,它有一列我想分开。 使用tidyr::separate截取的以下示例几乎可以完成此任务:

 tmp2 <- data.frame( varTreatName = c(
   "resp_Nadd_belowCanopy", "resp_NPadd_belowCanopy"
   , "resp_sd_Nadd_belowCanopy", "resp_sd_NPadd_belowCanopy"))
 tmp2 %>% separate(
    "varTreatName", c("varName","treatment","canopyPosition")
    , extra = "merge")
多个实例合并到一列中。但是,请注意,在所描述的情况下,第一个实例varName'resp_sd'包含的分隔符与 通过划分要分离的因素(治疗和位置)来使用。但是合并只发生在最后的实例上

因此,在上面示例的最后一行中,我希望提取:“resp_sd”、“NPadd”、“belowCanopy”


如何合并第一个实例而不是最后一个实例,以便仅分离最后n个实例?

在筛选已回答的类似问题时,我在中发现了
tidyr::extract
,可用于执行此任务:

 tmp2 %>% extract(
   "varTreatName", c("varName","treatment","canopyPosition")
   , regex = "(.*)_([^_]+)_([^_]+)$")
产生预期结果:

  varName treatment canopyPosition
1    resp      Nadd    belowCanopy
2    resp     NPadd    belowCanopy
3 resp_sd      Nadd    belowCanopy
4 resp_sd     NPadd    belowCanopy

tidyr::separate
接受正则表达式,因此您也可以执行以下操作:

library(dplyr)
library(tidyr)

tmp2 %>% 
  separate("varTreatName", c("varName","treatment","canopyPosition"), 
           , sep = "_(?!s)", extra = "merge")
结果:

  varName treatment canopyPosition
1    resp      Nadd    belowCanopy
2    resp     NPadd    belowCanopy
3 resp_sd      Nadd    belowCanopy
4 resp_sd     NPadd    belowCanopy

谢谢你的回答。你能解释一下分隔符上的正则表达式是如何工作的吗?在本例的一个微基准中,基于提取的解决方案大约快了三分之一。@ThomasWutzler
sep
使用正则表达式作为
sep
参数来拆分列<代码>\u(?!s)表示后面不跟s的文字“\u1”。所以我用所有下划线分割,除了
resp_sd
之间的下划线,因为下划线后面有一个“s”。@ThomasWutzler我认为
extract
更快,因为它只有一个匹配项,而
separate
有多个匹配项要搜索。感谢@useR对正则表达式的解释。我看到它非常特定于分隔符后面的示例中的模式。
  varName treatment canopyPosition
1    resp      Nadd    belowCanopy
2    resp     NPadd    belowCanopy
3 resp_sd      Nadd    belowCanopy
4 resp_sd     NPadd    belowCanopy