2009-12-09 2 views
28

Я пытаюсь прочитать текстовый файл с различными длинами строк:Импортировать данные в R с неизвестным количеством столбцов?

1 
1 2 
1 2 3 
1 2 3 4 
1 2 3 4 5 
1 2 3 4 5 6 
1 2 3 4 5 6 7 
1 2 3 4 5 6 7 8 

Чтобы преодолеть эту проблему, я использую заливку аргумент = TRUE, в read.table, так:

data<-read.table("test",sep="\t",fill=TRUE) 

к сожалению, оценить максимальную длину строки, read.table читает только первые 5 строк файла, и создает объект, глядя, как это:

data 
    V1 V2 V3 V4 V5 
1 1 NA NA NA NA 
2 1 2 NA NA NA 
3 1 2 3 NA NA 
4 1 2 3 4 NA 
5 1 2 3 4 5 
6 1 2 3 4 5 
7 6 NA NA NA NA 
8 1 2 3 4 5 
9 6 7 NA NA NA 
10 1 2 3 4 5 
11 6 7 8 NA NA 

есть Aw ay заставить read.table прокручивать весь файл, чтобы оценить максимальную длину строки? Я знаю, что возможное решение было бы указать номер столбца, как:

data<-read.table("test",sep="\t",fill=TRUE,col.names=c(1:8)) 

Но так как у меня есть много файлов, я хотел, чтобы оценить это автоматически в R. Любое предложение? :-)


EDIT: исходный файл не содержит прогрессивные номера, так что это не решение:

data1<-read.table("test",sep="\t",fill=TRUE) 
data2<-read.table("test",sep="\t",fill=TRUE,col.names=c(1:max(data1)) 
+0

вы можете поместить заголовок в файле (т.е. файлы имеют согласованный формат)? – Shane

+0

К сожалению, файлы не создаются извне, и каждая строка может иметь случайное количество записей. –

ответ

55

Существует хорошая функция count.fields (см справку), который подсчитывает количество столбца в строке:

count.fields("test", sep = "\t") 
#[1] 1 2 3 4 5 6 7 8 

Таким образом, используя ваше второе решение:

no_col <- max(count.fields("test", sep = "\t")) 
data <- read.table("test",sep="\t",fill=TRUE,col.names=1:no_col) 
data 
# X1 X2 X3 X4 X5 X6 X7 X8 
# 1 1 NA NA NA NA NA NA NA 
# 2 1 2 NA NA NA NA NA NA 
# 3 1 2 3 NA NA NA NA NA 
# 4 1 2 3 4 NA NA NA NA 
# 5 1 2 3 4 5 NA NA NA 
# 6 1 2 3 4 5 6 NA NA 
# 7 1 2 3 4 5 6 7 NA 
# 8 1 2 3 4 5 6 7 8 
+0

Блестящий. Элегантный и быстрый :-) –

+0

Хороший звонок. Я использую R больше года и никогда не сталкивался с этой функцией, даже если он находится прямо в конце документации read.table! –

+0

Хотелось бы, чтобы я мог дать более 1 upvote этому ответу! Настолько полезно! –

5

Использование count.fields, безусловно, правильный подход к этому, но только для полноты:

Другой вариант, чтобы ввести все необработанный текст и разобрать его в R:

x <- readLines(textConnection(
"1\t 
1\t2 
1\t2\t3 
1\t2\t3\t4 
1\t2\t3\t4\t5 
1\t2\t3\t4\t5\t6")) 
x <- strsplit(x,"\t") 

Чтобы объединить список неравные векторы длины, самый простой подход заключается в использовании rbind.fill функции от plyr:

library(plyr) 
# requires data.frames with column names 
x <- lapply(x,function(x) {x <- as.data.frame(t(x)); colnames(x)=1:length(x); return(x)}) 
do.call(rbind.fill,x) 
1 2 3 4 5 6 
1 1 <NA> <NA> <NA> <NA> <NA> 
2 1 2 <NA> <NA> <NA> <NA> 
3 1 2 3 <NA> <NA> <NA> 
4 1 2 3 4 <NA> <NA> 
5 1 2 3 4 5 <NA> 
6 1 2 3 4 5 6