不丢失字符的字符串拆分 - R

3

我有一个非常大的数据框,其中有两列数据很难拆分。以前我使用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中处理缺失数据的说明。
我看到这个网页提到在值之间添加一个空格,然后只需在空格上拆分,但我不知道如何解决以下问题:1)缺失数据,2)每行中没有一致的数字或字符值。

你仍然可以使用strsplit()函数,并通过使用perl保存分割值。你的代码是什么? - Rich Scriven
1个回答

4
我们遍历'df1'的列 (lapply(df1, ..),使用sub在数字子字符串后创建分隔符,使用read.tablevector读取为data.frame,rbind 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

或者使用tidyr中的separate函数。
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 完美解决了问题。谢谢。我还没有成功地适应第一个建议,但我会使用你在开头写出的逻辑,看看是否能够成功。 - Sam Marshal
@SamMarshal 或许你的原始数据集中存在一些与你展示的不匹配的模式。 - akrun
1
也许值得展示一下 data.table 的方法,它具有很好的 type.convert 特性(不确定 separate 是否有):data.table::tstrsplit(x, "(?<=[0-9])(?=[a-zA-Z])", perl=TRUE, type.convert=TRUE) - Frank
1
@akrun 那也是我的想法,所以我会逐步审查逻辑,看看是否能找到哪里出了问题。 - Sam Marshal
1
@Frank 是的,separate 也有那个选项,但默认情况下是 FALSE - akrun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接