※ 引述《gn01349943 (flying)》之铭言:
: 但我题目可能说的不够清楚,实际情况是有值项结束不是固定的,
: 这样就可能就需要再加个判断有多少数量在each row,
: 例如,资料可能长这样子,
: (dd <- data.table(x=1:6,b=c(2,'',4,5,6,7),c(1,'','',4,5,6),c(1,'','',4,5,'')
,c
: x b V3 V4 V5
: 1: 1 2 1 1
: 2: 2
: 3: 3 4
: 4: 4 5 4 4 4
: 5: 5 6 5 5 5
: 6: 6 7 6
: 想要变成这样的格式,
: x b V3 V4 V5
: 1 1 2 1 1
: 2 2
: 3 3 4
: 4 4 5 4 4 4
: 5 5 6 5 5 5
: 6 6 7 6
这个除了直转横做外,提供一个用regular expression的作法
当作csv档案,做一个平移的动作即可
好读版程式:http://pastebin.com/xh3qt4Xa
library(data.table)
library(dplyr)
library(magrittr)
(dt <- data.table(x=1:6,b=c(2,'',4,5,6,7),c(1,'','',4,5,6),c(1,'','',4,5,''),
c('','','',4,5,'')))
old_names = names(dt)
dt %<>% setnames(paste0("V", 1:ncol(dt)))
txt = dt %>% mutate_(Vcobime = paste0("paste(", paste0("V", 1:ncol(dt),
collapse = ","), ", sep = \",\")")) %>% .$Vcobime
loc = which(substr(txt, sapply(txt, nchar), sapply(txt, nchar)) == ",")
txt[loc] = gsub("(([^,]+,)*)(,*)", "\\3\\1", txt[loc]) %>%
substr(1, sapply(.,nchar)-1) %>% paste0(",", .)
dt = fread(paste(txt, collapse = "\n")) %>% setnames(old_names)
顺便补一个用20万列、100行的资料测试结果:
set.seed(100)
n_cols = 100
n_rows = 2e5
rightShift = sample(0:39, n_rows, TRUE)
m = matrix(rbinom(n_cols*n_rows, 10, 0.5), n_rows)
dt = t(sapply(1:n_rows, function(i){
c(as.character(m[i,1:(n_cols-rightShift[i])]), rep('', rightShift[i]))
})) %>% data.table
用regular expression 大概花 8秒 (amazing!!!)
用直转横再用.SD做平移大概花220秒
测试机器:RRO-3.2.0, windows 7 64bit, i7-3770K@4.4GHz, 16G ram