【问题标题】:How to split a string variable in variables in R (non-rectangular)如何在R中的变量中拆分字符串变量(非矩形)
【发布时间】:2023-03-28 09:56:01
【问题描述】:

我在数据框中有以下变量

test<-data.frame(x=c("", "1-7-9", "3", "2-4-6-8"))

我想将其拆分为以下变量:

Var1 Var2 Var3 Var4
NA   NA   NA   NA
1    7    9
3    NA   NA   NA
2    4    6   8

我试过了

 test2<-strsplit(as.character(vartest$x), "\\-")  

但我得到一个列表而不是数据框

请帮帮我

【问题讨论】:

    标签: r string split dataframe


    【解决方案1】:
    library(data.table)
    setDT(test)[, tstrsplit(x, "-", type.convert = TRUE, fixed = TRUE)]
    #    V1 V2 V3 V4
    # 1: NA NA NA NA
    # 2:  1  7  9 NA
    # 3:  3 NA NA NA
    # 4:  2  4  6  8
    

    注意:data.table dev version 1.9.5type.convert 参数和因子到字符的转换已在最新的开发版本中根据 #1094 实现(感谢 Arun!)。

    或者

    splitstackshape::cSplit(test, "x", "-")
    #    x_1 x_2 x_3 x_4
    # 1:  NA  NA  NA  NA
    # 2:   1   7   9  NA
    # 3:   3  NA  NA  NA
    # 4:   2   4   6   8
    

    这两个返回的数据表都可以通过分配结果然后使用setDF() 转换回数据帧。它们还都正确地将数字字符转换为分类的“整数”列。


    只是为了好玩,用scan()取回数据框的方法非常困难

    x <- as.character(test$x)
    v <- max(vapply(strsplit(x, "-", fixed = TRUE), length, 1L))
    s <- scan(text = x, what = as.list(integer(v)), sep = "-", fill = TRUE, 
        na.strings = "", blank.lines.skip = FALSE)
    setNames(data.frame(s), make.names(seq_along(s)))
    #   X1 X2 X3 X4
    # 1 NA NA NA NA
    # 2  1  7  9 NA
    # 3  3 NA NA NA
    # 4  2  4  6  8
    

    【讨论】:

    • 我有一种有趣的感觉,你要整晚都在添加解决方案:)
    • type.convert 上为tstrsplit 进行公关然后:)
    • 我想我可能会。我在聊天室 ping Arun
    【解决方案2】:

    其他一些选项

    library(tidyr) 
    separate(test, x, paste0("Var", 1:4), extra = "merge", convert = TRUE)
    #   Var1 Var2 Var3 Var4
    # 1   NA   NA   NA   NA
    # 2    1    7    9   NA
    # 3    3   NA   NA   NA
    # 4    2    4    6    8
    

    并且(部分使用您的解决方案 - 尽管类型没有保证)

    library(stringi)
    data.frame(stri_list2matrix(strsplit(as.character(test$x), "-", fixed = TRUE), byrow = TRUE)) 
    #    X1   X2   X3   X4
    # 1 <NA> <NA> <NA> <NA>
    # 2    1    7    9 <NA>
    # 3    3 <NA> <NA> <NA>
    # 4    2    4    6    8
    

    或者(由@Richard 提供)上述的完整stringi 版本

    data.frame(stri_split_fixed(test$x, "-", simplify = NA, omit_empty = NA))
    #     X1   X2   X3   X4
    # 1 <NA> <NA> <NA> <NA>
    # 2    1    7    9 <NA>
    # 3    3 <NA> <NA> <NA>
    # 4    2    4    6    8
    

    【讨论】:

    • 查看stringi::stri_split_fixed(test$x, "-", simplify = NA)
    • @RichardScriven 不错
    • 另外,stringi 会自动转换因子,所以我们不需要as.character(),这也很不错
    • 是的,它也有simplify 参数。而separate 显然有一个type.convert 参数......
    【解决方案3】:

    这是一个基本的尝试,尽管它无法用 NA 填充第一行,并且一些测试表明它永远不会将空字符项转换为 NA 的行。

    dat <- read.table(text=as.character(test$x), sep="-", 
                       fill =TRUE,col.names=paste0("Var", 1:4) )
    > dat
      Var1 Var2 Var3 Var4
    1    1    7    9   NA
    2    3   NA   NA   NA
    3    2    4    6    8
    

    【讨论】:

      【解决方案4】:

      使用基础 R:

      x <- strsplit(as.character(test$x),"-")
      nc <- max(sapply(x, length))
      out <- data.frame(do.call(rbind, lapply(x, "[", 1:nc)))
      names(out) <- paste("var", 1:nc, sep = "")
      
      > out
        var1 var2 var3 var4
      1 <NA> <NA> <NA> <NA>
      2    1    7    9 <NA>
      3    3 <NA> <NA> <NA>
      4    2    4    6    8
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-17
        • 2021-10-24
        相关资源
        最近更新 更多