【问题标题】:How to use separate() properly?如何正确使用分离()?
【发布时间】:2015-06-25 10:26:21
【问题描述】:

我在提取表单中的 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?

【问题讨论】:

  • 您需要 ID 和 NAME 还是只需要 ID?
  • 嗨,大卫,姓名是可选的。但是,看看如何提取名称会很棒。
  • NAME 的模式是什么,它有什么不同吗?
  • 变体带有下划线。它通常是大写字母

标签: regex r tidyr


【解决方案1】:

我认为您应该使用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

【讨论】:

    【解决方案2】:

    试试这个(假设 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"
    

    【讨论】:

    • 我认为 OP 实际上没有 NAME 字符串,这似乎只是为了说明。
    • 名称字符串是什么意思? df$a-vector 的每个元素开头的NAME_
    • 我的意思是可以包含任何字母,而不仅仅是NAME。这是我从 cmets 那里收集到的……但我可能错了
    • 啊好的,是的,在这种情况下我的解决方案不起作用,我更改了我的解决方案,以便无论第一个 _ 之前的部分是什么,它都能正常工作
    • 但你是对的,使用字符串很大程度上取决于基本假设,因此始终将它们包含在解决方案中很重要(我现在学到的一课)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-11
    • 1970-01-01
    • 2023-03-23
    • 2015-03-31
    • 2020-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多