在R中拆分列
我是R新手,我有一个17列超过1百万行的大数据集。我想通过分隔符“/”将其中一列拆分为4。R永远无法完成以下命令。是否有更好的方法完成以下内容。我已经给尽可能多的代码信息,并将感谢任何帮助在R中拆分列,r,splitstackshape,R,Splitstackshape,我是R新手,我有一个17列超过1百万行的大数据集。我想通过分隔符“/”将其中一列拆分为4。R永远无法完成以下命令。是否有更好的方法完成以下内容。我已经给尽可能多的代码信息,并将感谢任何帮助 sample2 <- read.csv("week1.csv", header=TRUE) summ1 <- subset(sample2,select= -c(3,7), subset =(SPORTS_ID =='1')) summ1 <- summ1[,-c(1)] library(s
sample2 <- read.csv("week1.csv", header=TRUE)
summ1 <- subset(sample2,select= -c(3,7), subset =(SPORTS_ID =='1'))
summ1 <- summ1[,-c(1)]
library(splitstackshape)
summ2 <- concat.split.multiple(summ1,2 , "/")
summ2 <- summ2[,-c(1,15)]
summ3 <- concat.split.multiple(summ2,14, "v")
write.csv(summm3, file="test.csv")
sample2这应该可以让您开始。您可能需要根据数据包含的内容调整正则表达式模式。一个可复制的例子会有所帮助。
库(stringr)
df如果要处理字符和不介意列表,stringr
包中的stru split
应该会有帮助
library(stringr)
x <- 'hello/hi/hey/hola'
str_split(x)
[[1]]
[1] "hello" "hi" "hey" "hola"
库(stringr)
x您可以使用strsplit
:
dat <- data.frame(a = c("a/b/c/d",
"e/f/g/h"),
stringsAsFactors = FALSE)
# a
# 1 a/b/c/d
# 2 e/f/g/h
cbind(dat, do.call(rbind, strsplit(dat$a, "/")))
# a 1 2 3 4
# 1 a/b/c/d a b c d
# 2 e/f/g/h e f g h
dat正如我在评论中提到的,如果您的数据是平衡的(也就是说,您希望在分割数据之后有一个漂亮的矩形数据集),那么您应该查看我的函数
这里有一些测试
Sven的数据,但有20K行而不是2行
但其他解决方案的效果如何
fun1 <- function() concat.split.multiple(dat, "a", "/")
fun2 <- function() do.call(rbind, strsplit(dat$a, "/", fixed=TRUE))
## ^^ fixed = TRUE will make a big difference
fun3 <- function() concat.split.DT(dat, "a", "/")
library(microbenchmark)
microbenchmark(fun1(), fun2(), fun3(), times = 10)
# Unit: milliseconds
# expr min lq median uq max neval
# fun1() 530.46597 534.13486 535.19139 538.91488 553.61919 10
# fun2() 30.22265 31.07287 31.81474 32.93936 40.28859 10
# fun3() 22.57517 22.94169 23.10297 23.30907 31.97640 10
concat.split.DT
方法的优点是可以使用简单的语法方便地拆分多个列:
dat2 <- do.call(cbind, replicate(5, dat, simplify = FALSE))
dim(dat2)
# [1] 1000000 5
names(dat2) <- make.unique(names(dat2))
head(dat2)
# a a.1 a.2 a.3 a.4
# 1 a/b/c/d a/b/c/d a/b/c/d a/b/c/d a/b/c/d
# 2 e/f/g/h e/f/g/h e/f/g/h e/f/g/h e/f/g/h
# 3 a/b/c/d a/b/c/d a/b/c/d a/b/c/d a/b/c/d
# 4 e/f/g/h e/f/g/h e/f/g/h e/f/g/h e/f/g/h
# 5 a/b/c/d a/b/c/d a/b/c/d a/b/c/d a/b/c/d
# 6 e/f/g/h e/f/g/h e/f/g/h e/f/g/h e/f/g/h
dat2很抱歉,如果没有一些示例数据,那么应该读取一列而不是我要拆分的行,这将很难提供帮助。此外,如果数据是平衡的,您可能希望放弃基本的concat.split.multiple
方法,并尝试我在这里进行的重写:可能重复我猜测的()这种方法不会非常有效。使用BaseR的字符串操作工具将更有效率。+1。为了提高效率,我会在您的strsplit中添加一个fixed=TRUE
。这是一个相当不错的主意。抱歉,但出于几个原因,这将是一个非常糟糕的主意。首先,如果(比如)你预计拆分结果会有20列,你打算这样做吗?最初的问题是预计会有4列新列。你还担心什么?另一个担心是“stringr”不一定能给你提速。更不用说,一个好的答案并不一定能解决问题中提到的眼前的问题,而是可能提出适用于更广泛情况的解决方案。嗨,伙计们,谢谢所有的回答,我会在一段时间内尝试这些。下面是数据列的副本,我将分为4个新列=英格兰足球/巴克莱超级联赛/赛程8月18日/阿森纳对桑德兰。我想将上述内容分解为英格兰足球,例如在列标题“联赛”下的一个列中,巴克莱超级联赛的下一个专栏是Comp等
library(stringr)
system.time(do.call(rbind, str_split(dat$a, "/")))
# user system elapsed
# 3.194 0.000 3.211
fun1 <- function() concat.split.multiple(dat, "a", "/")
fun2 <- function() do.call(rbind, strsplit(dat$a, "/", fixed=TRUE))
## ^^ fixed = TRUE will make a big difference
fun3 <- function() concat.split.DT(dat, "a", "/")
library(microbenchmark)
microbenchmark(fun1(), fun2(), fun3(), times = 10)
# Unit: milliseconds
# expr min lq median uq max neval
# fun1() 530.46597 534.13486 535.19139 538.91488 553.61919 10
# fun2() 30.22265 31.07287 31.81474 32.93936 40.28859 10
# fun3() 22.57517 22.94169 23.10297 23.30907 31.97640 10
dat <- do.call(rbind, replicate(50, dat, simplify=FALSE))
dim(dat)
# [1] 1000000 1
microbenchmark(fun2(), fun3(), times = 5)
# Unit: seconds
# expr min lq median uq max neval
# fun2() 6.257892 6.522199 13.728283 13.934860 14.277432 5
# fun3() 1.671739 1.830485 2.203076 2.470872 2.572917 5
dat2 <- do.call(cbind, replicate(5, dat, simplify = FALSE))
dim(dat2)
# [1] 1000000 5
names(dat2) <- make.unique(names(dat2))
head(dat2)
# a a.1 a.2 a.3 a.4
# 1 a/b/c/d a/b/c/d a/b/c/d a/b/c/d a/b/c/d
# 2 e/f/g/h e/f/g/h e/f/g/h e/f/g/h e/f/g/h
# 3 a/b/c/d a/b/c/d a/b/c/d a/b/c/d a/b/c/d
# 4 e/f/g/h e/f/g/h e/f/g/h e/f/g/h e/f/g/h
# 5 a/b/c/d a/b/c/d a/b/c/d a/b/c/d a/b/c/d
# 6 e/f/g/h e/f/g/h e/f/g/h e/f/g/h e/f/g/h
system.time(out <- concat.split.DT(dat2, names(dat2), "/"))
# user system elapsed
# 6.260 0.040 6.532
out
# a_1 a_2 a_3 a_4 a.1_1 a.1_2 a.1_3 a.1_4 a.2_1 a.2_2 a.2_3 a.2_4 a.3_1
# 1: a b c d a b c d a b c d a
# 2: e f g h e f g h e f g h e
# 3: a b c d a b c d a b c d a
# 4: e f g h e f g h e f g h e
# 5: a b c d a b c d a b c d a
# ---
# 999996: e f g h e f g h e f g h e
# 999997: a b c d a b c d a b c d a
# 999998: e f g h e f g h e f g h e
# 999999: a b c d a b c d a b c d a
# 1000000: e f g h e f g h e f g h e
# a.3_2 a.3_3 a.3_4 a.4_1 a.4_2 a.4_3 a.4_4
# 1: b c d a b c d
# 2: f g h e f g h
# 3: b c d a b c d
# 4: f g h e f g h
# 5: b c d a b c d
# ---
# 999996: f g h e f g h
# 999997: b c d a b c d
# 999998: f g h e f g h
# 999999: b c d a b c d
# 1000000: f g h e f g h