如何正确使用separate()?

时间:2015-06-25 10:26:22

标签: regex r tidyr

我在表单中提取ID时遇到了一些困难:

27da12ce-85fe-3f28-92f9-e5235a5cf6ac

来自数据框:

a<-c("NAME_27da12ce-85fe-3f28-92f9-e5235a5cf6ac_THOMAS_MYR",
        "NAME_94773a8c-b71d-3be6-b57e-db9d8740bb98_THIMO",
         "NAME_1ed571b4-1aef-3fe2-8f85-b757da2436ee_ALEX",
         "NAME_9fbeda37-0e4f-37aa-86ef-11f907812397_JOHN_TYA",
         "NAME_83ef784f-3128-35a1-8ff9-daab1c5f944b_BISHOP",
         "NAME_39de28ca-5eca-3e6c-b5ea-5b82784cc6f4_DUE_TO",
         "NAME_0a52a024-9305-3bf1-a0a6-84b009cc5af4_WIS_MICHAL",
         "NAME_2520ebbb-7900-32c9-9f2d-178cf04f7efc_Sarah_Lu_Van_Gar/Thomas")

基本上它是第一个和第二个下划线之间的东西。

通常我接近:

library(tidyr)
df$a<-as.character(df$a)
df<-df[grep("_", df$a), ]
df<- separate(df, a, c("ID","Name") , sep = "_")
df$a<-as.numeric(df$ID)

然而这次有许多下划线......我的方法失败了。有没有办法提取该ID?

2 个答案:

答案 0 :(得分:5)

我认为您应该使用extract代替separate。您需要指定要捕获的模式。我在这里假设ID始终以数字开头,所以我在第一个数字之后捕获所有内容,直到下一个_,然后是之后的所有内容

df <- data.frame(a)
df <- df[grep("_", df$a),, drop = FALSE]
extract(df, a, c("ID", "NAME"), "[A-Za-z].*?(\\d.*?)_(.*)")
#                                     ID                    NAME
# 1 27da12ce-85fe-3f28-92f9-e5235a5cf6ac              THOMAS_MYR
# 2 94773a8c-b71d-3be6-b57e-db9d8740bb98                   THIMO
# 3 1ed571b4-1aef-3fe2-8f85-b757da2436ee                    ALEX
# 4 9fbeda37-0e4f-37aa-86ef-11f907812397                JOHN_TYA
# 5 83ef784f-3128-35a1-8ff9-daab1c5f944b                  BISHOP
# 6 39de28ca-5eca-3e6c-b5ea-5b82784cc6f4                  DUE_TO
# 7 0a52a024-9305-3bf1-a0a6-84b009cc5af4              WIS_MICHAL
# 8 2520ebbb-7900-32c9-9f2d-178cf04f7efc Sarah_Lu_Van_Gar/Thomas

答案 1 :(得分:1)

尝试这个(假设ID始终是第一个unerscore之后的部分):

sapply(strsplit(a, "_"), function(x) x[[2]])

它为您提供了“中间部分”,即您的ID:

[1] "27da12ce-85fe-3f28-92f9-e5235a5cf6ac" "94773a8c-b71d-3be6-b57e-db9d8740bb98"
[3] "1ed571b4-1aef-3fe2-8f85-b757da2436ee" "9fbeda37-0e4f-37aa-86ef-11f907812397"
[5] "83ef784f-3128-35a1-8ff9-daab1c5f944b" "39de28ca-5eca-3e6c-b5ea-5b82784cc6f4"
[7] "0a52a024-9305-3bf1-a0a6-84b009cc5af4" "2520ebbb-7900-32c9-9f2d-178cf04f7efc"

如果你想得到一个简单的解决方案(假设名字总是在第二个下划线之后):

Names <- sapply(strsplit(a, "_"), function(x) Reduce(paste, x[-c(1,2)]))

给你这个:

[1] "THOMAS MYR"              "THIMO"                   "ALEX"                    "JOHN TYA"               
[5] "BISHOP"                  "DUE TO"                  "WIS MICHAL"              "Sarah Lu Van Gar/Thomas"