如何在R中的变量中拆分字符串变量(非矩形)

时间:2015-03-26 00:16:17

标签: r string split dataframe

我在数据框中有以下变量

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), "\\-")  

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

请帮帮我

4 个答案:

答案 0 :(得分:5)

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()分配结果转换回数据帧。他们也正确地将数字字符转换为分类&#34;整数&#34;列。


只是为了好玩,这是一种使用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

答案 1 :(得分:3)

其他一些其他选择

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

答案 2 :(得分:2)

这是一个基础尝试,虽然它无法使用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

答案 3 :(得分:0)

使用基数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