【问题标题】:strsplit split on either or depending onstrsplit 拆分取决于或取决于
【发布时间】:2018-04-23 15:28:27
【问题描述】:

我又一次为 苦苦挣扎。我正在将一些字符串转换为数据帧,但是有一个正斜杠 / 和我的字符串中的一些空白一直困扰着我。我可以解决它,但我很想知道我是否可以在 中使用一些花哨的东西。我下面的工作示例应该说明问题

我目前正在使用的 函数

str_to_df <- function(string){
t(sapply(1:length(string), function(x) strsplit(string, "\\s+")[[x]])) }

我得到的一种字符串,

string1 <- c('One\t58/2', 'Two 22/3', 'Three\t15/5')
str_to_df(string1)
#>      [,1]    [,2]  
#> [1,] "One"   "58/2"
#> [2,] "Two"   "22/3"
#> [3,] "Three" "15/5"

我在同一个地方找到的另一种类型,

string2 <- c('One 58 / 2', 'Two 22 / 3', 'Three 15 / 5')
str_to_df(string2)
#>      [,1]    [,2] [,3] [,4]
#> [1,] "One"   "58" "/"  "2" 
#> [2,] "Two"   "22" "/"  "3" 
#> [3,] "Three" "15" "/"  "5" 

它们显然会创建不同的输出,我不知道如何编写一个对两者都有效的解决方案。以下是我想要的结果。先感谢您!

desired_outcome <- structure(c("One", "Two", "Three", "58", "22",
                               "15", "2", "3", "5"), .Dim = c(3L, 3L))
desired_outcome
#>      [,1]    [,2] [,3]
#> [1,] "One"   "58" "2" 
#> [2,] "Two"   "22" "3" 
#> [3,] "Three" "15" "5"

【问题讨论】:

  • 您可以用任何非单词(字母数字)字符分割:t(simplify2array(strsplit(string1, '\\W+')))

标签: strsplit strsplit strsplit r dataframe strsplit


【解决方案1】:

这行得通:

str_to_df <- function(string){
  t(sapply(1:length(string), function(x) strsplit(string, "[/[:space:]]+")[[x]])) }

string1 <- c('One\t58/2', 'Two 22/3', 'Three\t15/5')
string2 <- c('One 58 / 2', 'Two 22 / 3', 'Three 15 / 5')

str_to_df(string1)
#      [,1]    [,2] [,3]
# [1,] "One"   "58" "2" 
# [2,] "Two"   "22" "3" 
# [3,] "Three" "15" "5"

str_to_df(string2)
#      [,1]    [,2] [,3]
# [1,] "One"   "58" "2" 
# [2,] "Two"   "22" "3" 
# [3,] "Three" "15" "5"

tidyr 的另一种方法可能是:

string1 %>% 
  as_tibble() %>% 
  separate(value, into = c("Col1", "Col2", "Col3"), sep = "[/[:space:]]+")

# A tibble: 3 x 3
#   Col1  Col2  Col3 
#   <chr> <chr> <chr>
# 1 One   58    2    
# 2 Two   22    3    
# 3 Three 15    5 

【讨论】:

  • 你不需要sapply,因为strsplit会为每个输入返回一个包含一个元素的列表,所以你可以使用simplify2array(这是sapply用来简化的), 所以t(simplify2array(strsplit(string, "[/[:space:]]+")))
【解决方案2】:

我们可以在一个或多个空格或制表符或正斜杠处创建split 的函数

f1 <- function(str1) do.call(rbind, strsplit(str1, "[/\t ]+"))
f1(string1)
#    [,1]    [,2] [,3]
#[1,] "One"   "58" "2" 
#[2,] "Two"   "22" "3" 
#[3,] "Three" "15" "5" 

f1(string2)
#     [,1]    [,2] [,3]
#[1,] "One"   "58" "2" 
#[2,] "Two"   "22" "3" 
#[3,] "Three" "15" "5" 

或者我们可以在用公共分隔符替换空格后使用read.csv

read.csv(text=gsub("[\t/ ]+", ",", string1), header = FALSE)
#     V1 V2 V3
#1   One 58  2
#2   Two 22  3
#3 Three 15  5

【讨论】:

  • 我真的很喜欢你的最后一个解决方案,即read.csv(text=gsub("[\t/ ]+", ",", sold_chr), header = FALSE),它甚至可以在没有数值的情况下处理,即string3 &lt;- c('One 58 / ', 'Two / 3', 'Three 15 / 5’)。我真的很感激。但是,我确实也意识到我确实有两个或多个单词的情况。也就是说,字母数字仇恨者之间的间距,即string4 &lt;- c('Two / 3', 'Three 15 / 5', ‘Four Cats / 5', ‘Five B dogs 7 / 0’) 你能否指出一个可以帮助我解决这个问题的资源,或者如果它不是太苛刻,你能提出一个解决方案吗?谢谢
  • @EricFail 你可以做read.csv(text=sub("^([A-Za-z ]+)\\s(\\d*)\\s*[/]\\s*(\\d*)$", "\\1,\\2,\\3", string4), header = FALSE, fill = TRUE)
猜你喜欢
  • 2021-09-28
  • 1970-01-01
  • 2013-12-05
  • 1970-01-01
  • 1970-01-01
  • 2022-06-14
  • 2022-10-14
  • 2011-09-30
  • 2016-11-30
相关资源
最近更新 更多