【问题标题】:How can I split a character string in a dataframe into multiple columns如何将数据框中的字符串拆分为多列
【发布时间】:2015-09-29 22:27:09
【问题描述】:

我正在使用一个数据框,其中一列包含的值主要是数字,但可能包含非数字条目。我想将此列拆分为多个列。其中一列应包含原始条目的数字部分,另一列应包含任何非数字元素。

这是一个示例数据框:

df <- data.frame(ID=1:4,x=c('< 0.1','100','A 2.5', '200')) 

这是我希望数据框的样子:

ID   x1   x2
1    <    0.1
2         100
3    A    2.5
4         200

我目前利用的数据的一个特点是字符串的结构总是如下:非数字元素(如果存在)总是在数字元素之前,两个元素总是用空间。

我可以使用 reshape 包中的 colsplit 根据空格拆分列。这样做的问题是它复制了任何不能分成两个元素的条目,

require(reshape)
df <- transform(df, x=colsplit(x,split=" ", names("x1","x2")))
df
ID  x1   x2
1   <    0.1
2   100  100
3   A    2.5
4   200  200

这不是什么大问题,因为我可以做一些后处理来从“x1”列中删除数字元素。

我还可以在函数中使用 strsplit 来完成我想做的事情:

split.fn <- function(id){
 new.val <- unlist(strsplit(as.character(df$x[df$ID==id])," "))
   if(length(new.val)==1){
     return(data.frame(ID=id,x1="NA",x2=new.val))
   }else{
     return(data.frame(ID=id,x1=new.val[1],x2=new.val[2]))
   }  

}
data.frame(rbindlist(lapply(unique(df$ID),split.fn)))
ID   x1   x2
1    <    0.1
2    NA   100
3    A    2.5
4    NA   200      

但这似乎很麻烦。

基本上我在这里列出的两个选项都可以使用。但我怀疑有一种更优雅或更直接的方法可以获取所需的数据框。

【问题讨论】:

    标签: r string split


    【解决方案1】:

    您可以使用 tidyr 中的separate()

    tidyr::separate(df, x, c("x1", "x2"), " ", fill = "left")
    #   ID   x1  x2
    # 1  1    < 0.1
    # 2  2 <NA> 100
    # 3  3    A 2.5
    # 4  4 <NA> 200
    

    如果您绝对需要删除 NA 值,那么您可以这样做

    tdy <- tidyr::separate(df, x, c("x1", "x2"), " ", fill = "left")
    tdy[is.na(tdy)] <- ""
    

    然后我们有

    tdy
    #   ID x1  x2
    # 1  1  < 0.1
    # 2  2    100
    # 3  3  A 2.5
    # 4  4    200
    

    【讨论】:

      【解决方案2】:

      这不使用任何包:

      transform(df,
        x1 = ifelse(grepl(" ", x), sub(" .*", "", x), NA),
        x2 = sub(".* ", "", paste(x)))
      

      给予:

        ID     x   x1  x2
      1  1 < 0.1    < 0.1
      2  2   100 <NA> 100
      3  3 A 2.5    A 2.5
      4  4   200 <NA> 200
      

      【讨论】:

        猜你喜欢
        • 2011-05-20
        • 2013-01-22
        相关资源
        最近更新 更多