Пересечение по спискам - PullRequest
0 голосов
/ 03 февраля 2020

У меня есть 6 текстовых файлов, разделенных на 2 группы (файлы A и T). я хочу импортировать все эти файлы в R и пересечь каждый файл A с каждым файлом T и получить матрицу с отношением A к T, как в этом примере. Я думал о том, чтобы составить два списка векторов и найти способ вычислить эту матрицу, начиная с них.

A_1.txt
tomato
zucchini
potato
banana
coconut
salt
A_2.txt
tomato
zucchini
potato
A_3.txt
zucchini
potato
T_1.txt
tomato
zucchini
potato
banana
coconut
salt
T_2.txt
tomato
zucchini
potato
banana
T_3.txt
potato
banana
coconut

я хочу получить следующую матрицу:

    T_1 T_2 T_3
A_1 6   4   3
A_2 3   3   1
A_3 2   2   1

Может кто-нибудь можете дать мне совет, как это сделать в R?

Я прочитал эту информацию следующим образом:

A_files <- list.files("/home/A/", full.names = TRUE)
T_files <- list.files("/home/T/", full.names = TRUE)
myAlist <- lapply(A_files, read.delim, header=FALSE)
myTlist <- lapply(T_files, read.delim, header=FALSE)

Ответы [ 2 ]

1 голос
/ 03 февраля 2020

Это то, что я бы сделал с моим предпочтительным набором инструментов:

library(data.table)
library(magrittr)
filenames <- dir(pattern = "^[AT]_\\d.txt$") 
vec <-
  lapply(filenames, fread, header = FALSE) %>% 
  set_names(filenames %>% stringr::str_remove("\\.txt$")) %>% 
  rbindlist(idcol = "file")
vecA <- vec[file %like% "^A"]
vecT <- vec[file %like% "^T"]
vecA[vecT, on = .(V1), allow.cartesian = TRUE] %>% 
  dcast(file ~ i.file, length)
   file T_1 T_2 T_3
1:  A_1   6   4   3
2:  A_2   3   3   1
3:  A_3   2   2   1

Объяснение

  1. Предположим, все файлы A_1.txt , A_2.txt, ..., T_2.txt, T_3.txt хранятся в той же папке, имена файлов выбираются.
  2. Все файлы считываются в список, элементы списка именуются соответственно, затем они объединяются в one data.table с дополнительным столбцом, в котором указан источник каждой строки.
  3. Затем два набора данных разделяются на vecA и vecT. (Это просто для ясности и для того, чтобы сделать код менее запутанным).
  4. Два набора данных объединены, и результат преобразуется из длинного в широкий формат с учетом количества общих элементов.

Результат объединения:

vecA[vecT, on = .(V1), allow.cartesian = TRUE]
    file       V1 i.file
 1:  A_1   tomato    T_1
 2:  A_2   tomato    T_1
 3:  A_1 zucchini    T_1
 4:  A_2 zucchini    T_1
 5:  A_3 zucchini    T_1
 6:  A_1   potato    T_1
 7:  A_2   potato    T_1
 8:  A_3   potato    T_1
 9:  A_1   banana    T_1
10:  A_1  coconut    T_1
11:  A_1     salt    T_1
12:  A_1   tomato    T_2
13:  A_2   tomato    T_2
14:  A_1 zucchini    T_2
15:  A_2 zucchini    T_2
16:  A_3 zucchini    T_2
17:  A_1   potato    T_2
18:  A_2   potato    T_2
19:  A_3   potato    T_2
20:  A_1   banana    T_2
21:  A_1   potato    T_3
22:  A_2   potato    T_3
23:  A_3   potato    T_3
24:  A_1   banana    T_3
25:  A_1  coconut    T_3
    file       V1 i.file

Воспроизводимые данные

Это способ создания 6 входных файлов из примера набора данных, представленного в вопрос:

library(data.table)
library(magrittr)
fread("A_1.txt
tomato
zucchini
potato
banana
coconut
salt
A_2.txt
tomato
zucchini
potato
A_3.txt
zucchini
potato
T_1.txt
tomato
zucchini
potato
banana
coconut
salt
T_2.txt
tomato
zucchini
potato
banana
T_3.txt
potato
banana
coconut", header = FALSE) %>% 
  .[, fwrite(.(V1[-1]), V1[1]), by = cumsum(V1 %like% "^[AT]_\\d.txt$")]
0 голосов
/ 03 февраля 2020

Вот подход с использованием базовых команд R. R по умолчанию создает факторы из векторов символов. Важно, чтобы вы этого не допустили. Включение аргумента as.is=TRUE в ваши команды read.csv сохранит символьные данные. Сначала сделайте данные легко доступными:

myAlist <- list(A_1 = c("tomato", "zucchini", "potato", "banana", "coconut", 
     "salt"), A_2 = c("tomato", "zucchini", "potato"), A_3 = c("zucchini", 
     "potato"))
myTlist <- list(T_1 = c("tomato", "zucchini", "potato", "banana", "coconut", 
     "salt"), T_2 = c("tomato", "zucchini", "potato", "banana"), T_3 = c("potato", 
     "banana", "coconut"))

Теперь мы создадим функцию для поиска пересечения двух групп и вычисления количества общих элементов:

Shared <- function(a, t) {
    length(intersect(myAlist[[a]], myTlist[[t]]))
}

Мы берем каждую группу в A и сравнивая его с каждой группой в B, например, A1 с B1, B2, B3 и т. д. c:

(A <- rep(1:3, each=3))
# [1] 1 1 1 2 2 2 3 3 3
(T <- rep(1:3, 3))
# [1] 1 2 3 1 2 3 1 2 3

Наконец, мы вычисляем количество общих элементов:

nshare <- mapply(Shared, A, T)
myTbl <- matrix(nshare, 3, byrow=TRUE, dimnames=list(A=names(myAlist), T=names(myTlist)))
myTbl
#      T
# A     T_1 T_2 T_3
#   A_1   6   4   3
#   A_2   3   3   1
#   A_3   2   2   1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...