Текстовый файл в списке в R
У меня есть большой текстовый файл с переменным количеством полей в каждой строке. Первая запись в каждой строке соответствует биологическому пути, и каждая последующая запись соответствует гена в этом пути. Первые несколько строк могут выглядеть так:
path1 gene1 gene2
path2 gene3 gene4 gene5 gene6
path3 gene7 gene8 gene9
Мне нужно прочитать этот файл в R в виде списка, причем каждый элемент является символьным вектором, а имя каждого элемента в списке является первым элементом в строке, например:
> pathways <- list(
+ path1=c("gene1","gene2"),
+ path2=c("gene3","gene4","gene5","gene6"),
+ path3=c("gene7","gene8","gene9")
+ )
>
> str(pathways)
List of 3
$ path1: chr [1:2] "gene1" "gene2"
$ path2: chr [1:4] "gene3" "gene4" "gene5" "gene6"
$ path3: chr [1:3] "gene7" "gene8" "gene9"
>
> str(pathways$path1)
chr [1:2] "gene1" "gene2"
>
> print(pathways)
$path1
[1] "gene1" "gene2"
$path2
[1] "gene3" "gene4" "gene5" "gene6"
$path3
[1] "gene7" "gene8" "gene9"
... но мне нужно сделать это автоматически для тысяч строк. Я видел аналогичный вопрос, размещенный здесь ранее, но я не мог понять, как это сделать из этого потока.
Спасибо заранее.
Ответы
Ответ 1
Вот один из способов сделать это:
# Read in the data
x <- scan("data.txt", what="", sep="\n")
# Separate elements by one or more whitepace
y <- strsplit(x, "[[:space:]]+")
# Extract the first vector element and set it as the list element name
names(y) <- sapply(y, `[[`, 1)
#names(y) <- sapply(y, function(x) x[[1]]) # same as above
# Remove the first vector element from each list element
y <- lapply(y, `[`, -1)
#y <- lapply(y, function(x) x[-1]) # same as above
Ответ 2
Одним из решений является считывание данных через read.table()
, но используйте аргумент fill = TRUE
для ввода строк с меньшим количеством "записей", преобразования результирующего фрейма данных в список и затем очистки "пустых" элементов.
Сначала прочитайте свой фрагмент данных в:
con <- textConnection("path1 gene1 gene2
path2 gene3 gene4 gene5 gene6
path3 gene7 gene8 gene9
")
dat <- read.table(con, fill = TRUE, stringsAsFactors = FALSE)
close(con)
Затем мы удаляем первый столбец, сначала сохраняя его для имен списка позже
nams <- dat[, 1]
dat <- dat[, -1]
Преобразование фрейма данных в список. Здесь я просто разбил кадр данных на индексы 1,2,..., n, где n - количество строк:
ldat <- split(dat, seq_len(nrow(dat)))
Очистите пустые ячейки:
ldat <- lapply(ldat, function(x) x[x != ""])
Наконец, примените имена
names(ldat) <- nams
Дарение:
> ldat
$path1
[1] "gene1" "gene2"
$path2
[1] "gene3" "gene4" "gene5" "gene6"
$path3
[1] "gene7" "gene8" "gene9"
Ответ 3
Быстрое решение на основе связанной страницы...
inlist <- strsplit(readLines("file.txt"), "[[:space:]]+")
pathways <- lapply(inlist, tail, n = -1)
names(pathways) <- lapply(inlist, head, n = 1)
Ответ 4
Еще одно решение:
sl <- c("path1 gene1 gene2", "path2 gene1 gene2 gene3") # created by readLines
f <- function(l, s) {
v <- strsplit(s, " ")[[1]]
l[[v[1]]] <- v[2:length(v)]
return(l)
}
res <- Reduce(f, sl, list())