【问题标题】:How to split a character column into multiple columns in R如何在R中将字符列拆分为多列
【发布时间】:2016-07-19 12:19:25
【问题描述】:

我有一个数据框x:

dput(x)
structure(list(District = structure(c(6L, 6L, 6L, 6L, 6L, 6L), .Label = c("District - Central (06)", 
"District - East (04)", "District - New Delhi (05)", "District - North (02)", 
"District - North East (03)", "District - North West (01)", "District - South (09)", 
"District - South West (08)", "District - West (07)"), class = "factor"), 
    Age = structure(c(103L, 1L, 2L, 14L, 25L, 36L), .Label = c("0", 
    "1", "10", "100+", "11", "12", "13", "14", "15", "16", "17", 
    "18", "19", "2", "20", "21", "22", "23", "24", "25", "26", 
    "27", "28", "29", "3", "30", "31", "32", "33", "34", "35", 
    "36", "37", "38", "39", "4", "40", "41", "42", "43", "44", 
    "45", "46", "47", "48", "49", "5", "50", "51", "52", "53", 
    "54", "55", "56", "57", "58", "59", "6", "60", "61", "62", 
    "63", "64", "65", "66", "67", "68", "69", "7", "70", "71", 
    "72", "73", "74", "75", "76", "77", "78", "79", "8", "80", 
    "81", "82", "83", "84", "85", "86", "87", "88", "89", "9", 
    "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", 
    "Age not stated", "All ages"), class = "factor"), Total = c(3656539L, 
    56131L, 58644L, 63835L, 63859L, 64945L), Rural = c(213950L, 
    3589L, 3757L, 4200L, 4102L, 4223L), Urban = c(3442589L, 52542L, 
    54887L, 59635L, 59757L, 60722L)), .Names = c("District", 
"Age", "Total", "Rural", "Urban"), row.names = c(NA, 6L), class = "data.frame")

我想拆分District 列以将区名提取到新列Name。例如。 “District - North West (01)”应该拆分为“North West”。 我试过str_split_fixed 得到:

x
                    District      Age   Total  Rural   Urban 1    name
1 District - North West (01) All ages 3656539 213950 3442589      North West (01)
2 District - North West (01)        0   56131   3589   52542      North West (01)
3 District - North West (01)        1   58644   3757   54887      North West (01)
4 District - North West (01)        2   63835   4200   59635      North West (01)
5 District - North West (01)        3   63859   4102   59757      North West (01)
6 District - North West (01)        4   64945   4223   60722      North West (01)

我尝试再次使用相同的函数来拆分name 列以将区域名称与代码分开,但它给了我以下错误:

stri_split_regex 中的错误(字符串,模式,n = n,简化 = TRUE,opts_regex = attr(模式,: 正则表达式模式中不正确的嵌套括号。 (U_REGEX_MISMATCHED_PAREN)

有没有办法根据单个函数中的模式将字符列拆分为多列?

【问题讨论】:

  • 你可以在这里使用Strsplit()
  • @PankajKaundal:我试过了,但结果是一个列表。此外,从名称中拆分代码的问题仍然是一个问题。例如。将“North West”与“(01)”分开。

标签: r split stringr


【解决方案1】:

你可以使用

library(stringr)

data.frame(str_split_fixed(df$District, " ", 3))

    X1      X2      X3
1 District   -    North West (01)
2 District   -    North West (01)
3 District   -    North West (01)
4 District   -    North West (01)
5 District   -    North West (01)
6 District   -    North West (01)

您可以使用gsub 删除您在此处拥有的多余内容,

gsub("[[:digit:]]","",df$X3)
gsub("[[:punct:]]","",df$X3)

等等

【讨论】:

  • 您需要提及您使用的任何外部包。 (顺便说一句,很好的解决方案)
  • 或者可以直接使用data.frame(str_split_fixed(a$District, " ", 4))。谢谢!
  • @rar : 如果我们将其除以 4,那么 North 和 West 将进入不同的列,因为它们之间有一个空格。
【解决方案2】:

你可以通过gsub得到你想要的:

gsub("^.* +- +([A-Za-z ]+) \\(.*$", "\\1", df$District)
[1] "North West" "North West" "North West" "North West" "North West" "North West"

gsub("^.* +- +([A-Za-z ]+) \(.*$") 的第一个参数是一个正则表达式,可以解释如下:

从字符串“^”的开头,匹配任何字符“.*”,后跟至少一个空格、一个连字符和至少一个空格“+- +”。然后捕获由(至少一个)字母和空格“[A-Za-z ]+”组成的下一个文本“()”。当您到达空格后跟括号“\\(”时停止捕获,然后匹配所有内容,直到文本“.*$”结束。

gsub 的第二个参数“\\1”表示用括号捕获的文本替换文本。

将其分配给变量:

df$name <- gsub("^.* +- +([A-Za-z ]+) \\(.*$", "\\1", df$District)

【讨论】:

  • @Imo:谢谢!它工作得很好。你能解释一下这是如何工作的吗?
  • 当然可以。请参阅解释我使用的正则表达式的编辑。熟悉这个工具非常有用,因为正则表达式在软件中广泛使用。
【解决方案3】:

还可以匹配提取:

library(stringi)
library(dplyr)
library(purrr)

mutate(x,
       name=map_chr(stri_match_all_regex(District, "- ([[:alpha:]]+ [[:alpha:]]+) "), function(x) x[,2]),
       code=map_chr(stri_match_all_regex(District, "\\(([[:digit:]]+)\\)"), function(x) x[,2]))

##                     District      Age   Total  Rural   Urban       name code
## 1 District - North West (01) All ages 3656539 213950 3442589 North West   01
## 2 District - North West (01)        0   56131   3589   52542 North West   01
## 3 District - North West (01)        1   58644   3757   54887 North West   01
## 4 District - North West (01)        2   63835   4200   59635 North West   01
## 5 District - North West (01)        3   63859   4102   59757 North West   01
## 6 District - North West (01)        4   64945   4223   60722 North West   01

【讨论】:

    猜你喜欢
    • 2021-10-29
    • 1970-01-01
    • 2021-03-07
    • 2014-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-06
    相关资源
    最近更新 更多