【问题标题】:Split String without losing character- R在不丢失字符的情况下拆分字符串-R
【发布时间】:2016-09-10 16:58:35
【问题描述】:

我在一个更大的数据框中有两列,我很难拆分。过去,当我尝试使用“空格”、“”或其他分隔符进行拆分时,我曾使用过strsplit。这里的难点是我不想丢失任何信息,当我拆分某些部分时,我最终会丢失信息。我想最后有四列。这是我现在拥有的几行的示例。

age-gen  surv-camp
45M      1LC
9F       0
12M      1AC
67M      1LC

这是我最终想要得到的。

age   gen   surv   camp
45    M     1      LC
9     F     0      
12    M     1      AC
67    M     1      LC

我在这里做了很多搜索,并在 Java、C++、html 等中找到了许多响​​应,但我还没有找到任何解释如何在 R 中执行此操作以及何时执行此操作的内容缺少数据。

我看到this 在值之间添加一个空格然后只是在空格上拆分,但我不明白这将如何工作 1) 缺少数据,2) 当我没有一致的数字或字符时每行的值。

【问题讨论】:

  • 您仍然可以使用strsplit() 并使用perl 保存拆分值。你的代码是什么?

标签: r strsplit


【解决方案1】:

我们遍历 'df1' (lapply(df1, ..) 的列,使用sub 在数字子字符串后创建一个分隔符,将vector 读取为带有read.tablerbind 和@987654326 的data.frame @ of data.frames 并更改输出的列名。

res <- do.call(cbind, lapply(df1, function(x)
      read.table(text=sub("(\\d+)", "\\1,", x), 
          header=FALSE, sep=",", stringsAsFactors=FALSE)))
colnames(res) <- scan(text=names(df1), sep=".", what="", quiet = TRUE)
res
#  age gen surv camp
#1  45   M    1   LC
#2   9   F    0     
#3  12   M    1   AC
#4  67   M    1   LC

或者使用来自tidyrseparate

library(tidyr)
library(dplyr)
separate(df1, age.gen, into = c("age", "gen"), "(?<=\\d)(?=[A-Za-z])", convert= TRUE) %>% 
       separate(surv.camp, into = c("surv", "camp"), "(?<=\\d)(?=[A-Za-z])", convert = TRUE)
#  age gen surv camp
#1  45   M    1   LC
#2   9   F    0 <NA>
#3  12   M    1   AC
#4  67   M    1   LC

或者正如@Frank所说,我们可以使用data.table中的tstrsplit

library(data.table)
setDT(df1)[, unlist(lapply(.SD, function(x) 
    tstrsplit(x, "(?<=[0-9])(?=[a-zA-Z])", perl=TRUE, 
                        type.convert=TRUE)), recursive = FALSE)]

编辑:在separate 中添加convert = TRUE 以更改拆分后列的type

数据

df1 <- structure(list(age.gen = c("45M", "9F", "12M", "67M"), surv.camp = c("1LC", 
 "0", "1AC", "1LC")), .Names = c("age.gen", "surv.camp"), 
class = "data.frame", row.names = c(NA, -4L))

【讨论】:

  • 使用separate 效果很好。谢谢你。我无法调整第一个建议并让它成功运行,但我会使用你一开始写的逻辑,看看我是否走运。
  • @SamMarshal 也许您的原始数据集的某些模式与您显示的模式不匹配。
  • 也许值得展示 data.table 方式,它有很好的type.convert 功能(不确定separate 是否有):data.table::tstrsplit(x, "(?&lt;=[0-9])(?=[a-zA-Z])", perl=TRUE, type.convert=TRUE)
  • @akrun 这也是我的想法,所以我会按照每个步骤中的逻辑工作,看看我是否能找到卡住的地方。
  • @Frank 是的separate 也有这个选项,但默认是FALSE
猜你喜欢
  • 2017-05-29
  • 2014-06-11
  • 1970-01-01
  • 1970-01-01
  • 2020-04-09
  • 2013-04-10
  • 1970-01-01
  • 2013-05-10
  • 1970-01-01
相关资源
最近更新 更多