Выбор указанных c строк файла с разделителями табуляции с помощью bash (linux) - PullRequest
0 голосов
/ 21 января 2020

У меня есть много каталогов txt файлов, разделенных табуляцией, с несколькими строками и столбцами, например,

File1
Id    Sample   Time ...  Variant[Colummn16] ...
1     s1       t0        c.B481A:p.G861S
2     s2       t2        c.C221C:p.D461W
3     s5       t1        c.G31T:p.G61R
File2
Id    Sample   Time ...  Variant[Colummn16] ...
1     s1       t0        c.B481A:p.G861S
2     s2       t2        c.C21C:p.D61W
3     s5       t1        c.G1T:p.G1R

, и мне нужно создать новый файл с:

  • все различные варианты uniq
  • количество повторяющихся вариантов
  • и местоположение файла

т.е.:

NewFile
Variant             Nº of repeated       Location
c.B481A:p.G861S     2                    File1,File2
c.C221C:p.D461W     1                    File1
c.G31T:p.G61R       1                    File1
c.C21C:p.D61W       1                    File2
c.G1T:p.G1R         1                    File2

Я думаю, что при использовании сценария basi c в bash с awk sort и uniq это будет работать, но я не знаю, с чего начать. Или, если использовать Rstudio или python (3) проще, я мог бы попробовать.

Спасибо !!

Ответы [ 3 ]

2 голосов
/ 21 января 2020

Чистый bash. Требуется версия 4.0 +

# two associative arrays
declare -A files
declare -A count

# use a glob pattern that matches your files
for f in File{1,2}; do
    {
        read header
        while read -ra fields; do
            variant=${fields[3]}        # use index "15" for 16th column
            (( count[$variant] += 1 ))
            files[$variant]+=",$f"
        done
    } < "$f"
done

for variant in "${!count[@]}"; do
    printf "%s\t%d\t%s\n" "$variant" "${count[$variant]}" "${files[$variant]#,}"
done

output

c.B481A:p.G861S 2   File1,File2
c.G1T:p.G1R 1   File2
c.C221C:p.D461W 1   File1
c.G31T:p.G61R   1   File1
c.C21C:p.D61W   1   File2

Порядок выходных строк не определен: ассоциативные массивы не имеют определенного порядка.

1 голос
/ 21 января 2020

Чисто bash было бы тяжело, я думаю, но у каждого есть какой-то аук: D

awk 'FNR==1{next}
{
  ++n[$16];
  if ($16 in a) {
    a[$16]=a[$16]","ARGV[ARGIND]
  }else{
    a[$16]=ARGV[ARGIND]
  }
}
END{
printf("%-24s %6s    %s\n","Variant","Nº","Location");
for (v in n) printf("%-24s %6d    %s\n",v,n[v],a[v])}' *
1 голос
/ 21 января 2020

Я предполагаю, что есть решение python или bash, которое является более кратким, но здесь есть относительно простое решение R, которое использует функции обратного хода (хотя вы можете повторить его в data.table или базе R, если хотите ). Например, я загрузил ваши данные в свой рабочий каталог, но я не рекомендую полагаться на ваш рабочий каталог в R (здесь он воспроизводим, хотя :)). Как отмечает Грегор, вы можете проверить пакет here или использовать проекты , или вы можете использовать абсолютные пути, если вы не беспокоитесь о переносимости с коллегами за пределами вашей системы.

Конечно, отсюда вы можете очистить вывод, чтобы он выглядел именно так, как вы хотите. Кроме того, я использовал readr::read_csv() для примера, но вы, вероятно, захотите использовать readr::read_delim() с delim = "\t" или просто использовать data.table::fread().

Решение :

library(dplyr)

# Get the file paths
file_paths <- list.files(pattern = "File\\d", full.names = T)

# Use the paths to read the data into a list (sapply retains the names)
list_of_files <- sapply(file_paths, read_csv, simplify = F)

# Create a data.frame from your list
df <- bind_rows(list_of_files, .id = "Location")

# Summarising the variables by grouping by the variant and counting & concatenating
df %>%
  mutate(Location = gsub(".*?/([[:alnum:]]+).*", "\\1", Location)) %>% #using regex to simplify file name
  group_by(Variant.Colummn16.) %>%
  summarise(n = n(), 
            Location = paste0(Location, collapse = ", "))

# A tibble: 5 x 3
  Variant.Colummn16.     n Location    
  <chr>              <int> <chr>       
1 c.B481A:p.G861S        2 File1, File2
2 c.C21C:p.D61W          1 File2       
3 c.C221C:p.D461W        1 File1       
4 c.G1T:p.G1R            1 File2       
5 c.G31T:p.G61R          1 File1   

Данные (и сохранение в wd):

library(readr)

File1 <- read.table(header = T, text = "Id    Sample   Time Variant[Colummn16]
1     s1       t0        c.B481A:p.G861S
2     s2       t2        c.C221C:p.D461W
3     s5       t1        c.G31T:p.G61R")


File2 <- read.table(header = T, text = "Id    Sample   Time  Variant[Colummn16]
1     s1       t0        c.B481A:p.G861S
2     s2       t2        c.C21C:p.D61W
3     s5       t1        c.G1T:p.G1R")

write_csv(File1, "File1.csv")
write_csv(File2, "File2.csv")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...