2016-08-19 2 views
1

У меня есть много .txt файлов, которые обычно имеют 5 столбцов, но некоторые строки больше, например:склеить столбцы запятых .txt файлов

a,b,c,d,e 
a,b,c,d,e 
a,b,c,d,e 
a,b,c,d,e,f,g 
a,b,c,d,e 

Все, что я хочу сделать, это склеить все столбцы которые простираются дальше пятой колонны. Приведенный выше пример должен привести к:

a,b,c,d,e 
a,b,c,d,e 
a,b,c,d,e 
a,b,c,d,e f g 
a,b,c,d,e 

Как я мог запрограммировать это в R?

+1

Вы делаете это прямо из файла или уже прочитали данные? –

+1

Привет, спасибо огромное, я этого не знал! Ваш ответ был очень полезным, и вы были правы предположить, что мои данные в R уже были через функцию read.csv, которую я знал «от» заранее, и что я не знал, что делаю при переполнении стека! :) Еще раз спасибо! – snarble

ответ

5

Я предполагаю, что вы уже прочитали файл ".csv" в R, через:

dat <- read.csv(file, header = FALSE, fill = TRUE) 

Небольшой тест на вашей предоставленной информации:

x <- "a,b,c,d,e 
     a,b,c,d,e 
     a,b,c,d,e 
     a,b,c,d,e,f,g 
     a,b,c,d,e" 

dat <- read.csv(text = x, header = FALSE, fill = TRUE) 

#   V1 V2 V3 V4 V5 V6 V7 
#1   a b c d e  
#2   a b c d e  
#3   a b c d e  
#4   a b c d e f g 
#5   a b c d e  

Возможно, это еще одна возможность?

from <- 5 
dat[, from] <- do.call(paste, dat[from:ncol(dat)]) ## merge and overwrite 
dat[, (from+1):ncol(dat)] <- NULL ## drop 

#   V1 V2 V3 V4 V5 
#1   a b c d e 
#2   a b c d e 
#3   a b c d e 
#4   a b c d e f g 
#5   a b c d e 

Мой простой подход требует, чтобы вы заранее знаете from; но, похоже, вы это знаете.

3

Мы можем читать набор данных, используя readLines, расколоть «линии» на «» в list, найти минимум length в list („MINLENGTH“), создать логическое условие („i1“), подмножество 'lst' и paste элементов, которые больше, чем 'minLength' вместе, и используют ifelse для создания вектора.

lines <- readLines("yourfile.txt") 
lst <- strsplit(lines, ",") 
minLength <- min(lengths(lst)) 
i1 <- lengths(lst) > minLength 
v1 <- sapply(lst[i1], function(x) paste(x[(minLength+1):length(x)], collapse=" ")) 
v2 <- ifelse(i1, v1, "") 

ПРИМЕЧАНИЕ. Для этого не требуется считывать данные и проверять, сколько столбцов имеется. Он автоматически найдет количество допустимых столбцов и вставляет другие.

После создания вектора («v2»), мы можем читать «линии» с read.csv и fill = TRUE

df1 <- read.csv(text = lines, header = FALSE, fill = TRUE) 
df1$newCol <- v2 

Или мы можем сразу прочитать файл с read.csv и найти столбец, который будет иметь первое значение NA или «». Когда есть 100s колонн с 1000ми линиями, становится трудно проверить, где первый NA или "" начинается (при условии, что нет никаких других NA или "" в наборе данных)

df1 <- read.csv("yourfile.txt", header = FALSE, fill = TRUE) 
i1 <- which.max(colSums(dat=="")!=0) 
#i1 <- which.max(colSums(is.na(dat))!=0) #if it is NA 
transform(df1[seq(i1-1)], newCol= do.call(paste, df1[i1:ncol(df1)])) 
#  V1 V2 V3 V4 V5 newCol 
#1  a b c d e  
#2  a b c d e  
#3  a b c d e  
#4  a b c d e f g 
#5  a b c d e  

ПРИМЕЧАНИЕ: Когда я отправил первый я использовал do.call(paste


Еще один подход будет использовать count.fields

i1 <- min(count.fields("yourfile.txt", sep=",")) 

затем прочитайте набор данных, используя read.csv/read.table и transform данные, как в приведенном выше подходе.

2

Если вы на системе Unix на базе, вы можете просто предварительно обработать файл перед тем загружая его в R (например, файл ff.txt):

$ paste -d ',' <(cut -f 1-4 -d ',' ff.txt) <(cut -f 5- -d ',' ff.txt | tr ',' ' ') > ff-mod.txt 

который записывает новый файл ff-mod.txt:

$ cat ff-mod.txt 
a,b,c,d,e 
a,b,c,d,e 
a,b,c,d,e 
a,b,c,d,e f g 
a,b,c,d,e 

файл может быть легко прочитан в R:

> read.table('ff-mod.txt', sep=',') 
    V1 V2 V3 V4 V5 
1 a b c d  e 
2 a b c d  e 
3 a b c d  e 
4 a b c d e f g 
5 a b c d  e 
Смежные вопросы