首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >拆分列-但仅当它包含一个或多个特殊字符时

拆分列-但仅当它包含一个或多个特殊字符时
EN

Stack Overflow用户
提问于 2020-12-17 17:38:13
回答 3查看 38关注 0票数 2

我发现了一些朝这个方向发展的问题,但我无法将解决方案应用于我的特定问题:我有一个相当混乱的数据帧列,其中包含地址。这意味着,可以有空单元格、数字、数字和文本组合在一起-之间可以有一个或多个特殊字符。

在第一步中,我想拆分第一个特殊字符处的所有值。我尝试了各种部分有效的选项。然而,问题似乎是一些单元格不包含任何特殊字符-导致函数中出现错误。

例如,下面的代码只将特殊字符放在新列b中,但并不真正拆分这些列:

代码语言:javascript
复制
df <- df %>% 
separate(address, into = c("a", "b"), sep = "[^[:punct:]]+", remove = FALSE)

所以,理想情况下我想实现的是:如果单元格中有一个特殊字符,在第一个特殊字符处拆分它,在column a中拆分第一个特殊字符的所有剩余部分,在column b中拆分所有正确的部分。如果没有特殊字符,则将整个内容放在column a中,将NA放在column b中。

我必须将我的代码包装在ifelse-statement中吗?或者还有其他的建议吗?

谢谢!

编辑:应要求,以下是一些示例数据:

代码语言:javascript
复制
library(dplyr)

test <- as.data.frame(c("2", "97/7", "17/7-8", "7E", "800E/7", "17", "", "0", "2/15", "17+18", "17/7/8", "19", "2/2/4", "9-7/8")) %>% 
  rename(address = 1)
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-12-17 18:36:13

您可以通过extra = 'merge'fill = 'right'使用separate

代码语言:javascript
复制
tidyr::separate(test, address, into = c("a", "b"), '[[:punct:]]', 
                extra = 'merge', fill = 'right', remove = FALSE)

#   address    a    b
#1        2    2 <NA>
#2     97/7   97    7
#3   17/7-8   17  7-8
#4       7E   7E <NA>
#5   800E/7 800E    7
#6       17   17 <NA>
#7               <NA>
#8        0    0 <NA>
#9     2/15    2   15
#10   17+18   17   18
#11  17/7/8   17  7/8
#12      19   19 <NA>
#13   2/2/4    2  2/4
#14   9-7/8    9  7/8
票数 1
EN

Stack Overflow用户

发布于 2020-12-17 18:24:33

在您的正则表达式中使用strsplit是可行的。我们可以把它放在一个lapply中,循环遍历这些列。使用`length<-()`,我们将列表元素的长度调整到最大值,以便能够创建一个data.frame

代码语言:javascript
复制
r <- el(lapply(test, strsplit, "[[:punct:]]", perl=TRUE))
as.data.frame(t(sapply(r, `length<-`, max(lengths(r)))))
#      V1   V2   V3
# 1     2 <NA> <NA>
# 2    97    7 <NA>
# 3    17    7    8
# 4    7E <NA> <NA>
# 5  800E    7 <NA>
# 6    17 <NA> <NA>
# 7  <NA> <NA> <NA>
# 8     0 <NA> <NA>
# 9     2   15 <NA>
# 10   17   18 <NA>
# 11   17    7    8
# 12   19 <NA> <NA>
# 13    2    2    4
# 14    9    7    8

类似地,我们可以在第一次出现时这样做:我们可以使用sub将第一次出现的内容替换为某个东西,比如"£",然后在那里拆分它。

代码语言:javascript
复制
test[] <- lapply(test, sub, pat="[[:punct:]]", rep="£")
r <- el(lapply(test, strsplit, "£"))
as.data.frame(t(sapply(r, `length<-`, max(lengths(r)))))
#      V1   V2
# 1     2 <NA>
# 2    97    7
# 3    17  7-8
# 4    7E <NA>
# 5  800E    7
# 6    17 <NA>
# 7  <NA> <NA>
# 8     0 <NA>
# 9     2   15
# 10   17   18
# 11   17  7/8
# 12   19 <NA>
# 13    2  2/4
# 14    9  7/8
票数 1
EN

Stack Overflow用户

发布于 2020-12-17 17:48:44

这样做是可行的:

代码语言:javascript
复制
library(dplyr)
library(tidyr)
df %>% separate(c1, c('a','b'), sep = '[^A-z0-9_]')
     a    b
1   ab   cd
2   pq   rj
3   xy    z
4 abcd <NA>

使用的数据:

代码语言:javascript
复制
df
     c1
1 ab$cd
2 pq%rj
3  xy#z
4  abcd
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65338096

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档