Функция Apply (), как она работает и где я не прав? - PullRequest
0 голосов
/ 28 июня 2019

Мне нужно преобразовать с помощью str_split большой data_frame. Идея состоит в том, чтобы проверить, равно ли значение в 2 столбцах != 0, и разделить их на "_" в новых столбцах. Я хочу сохранить новые значения в 3 новых столбцах. Я думал о цикле for, но это займет вечность, и я хотел использовать apply(), но он не работает.

data.frame:

a <- structure(list(seqnames1 = c("chr1", "chr1", "chr1", "chr1",  "chr1",
"chr1"), start1 = c(4207675L, 4207675L, 4207675L, 4207675L,  4207675L,
4207675L), end1 = c(4207887L, 4207887L, 4207887L, 4207887L,  4207887L,
4207887L), width1 = c(213L, 213L, 213L, 213L, 213L,  213L), strand1 =
c("*", "*", "*", "*", "*", "*"), node.class1 = c("bait",  "bait",
"bait", "bait", "bait", "bait"), promoter.id1 = c(0L,  0L, 0L, 0L, 0L,
0L), promoter_flanking_region.id1 = c(0L, 0L,  0L, 0L, 0L, 0L),
exon.id1 = c(0L, 0L, 0L, 0L, 0L, 0L), intron.id1 = c(0L,  0L, 0L, 0L,
0L, 0L), enhancer.id1 = c(0L, 0L, 0L, 0L, 0L, 0L), 
    fli1.id1 = c(0L, 0L, 0L, 0L, 0L, 0L), gata1.id1 = c(0L, 0L, 
    0L, 0L, 0L, 0L), gata2.id1 = c(0L, 0L, 0L, 0L, 0L, 0L), tal1.id1 = c(0L, 
    0L, 0L, 0L, 0L, 0L), ctcf.id1 = c(0L, 0L, 0L, 0L, 0L, 0L), 
    bait.id1 = c("chr1:4267838-4267939", "chr1:4267838-4267939", 
    "chr1:4267838-4267939", "chr1:4267838-4267939", "chr1:4267838-4267939", 
    "chr1:4267838-4267939"), gene_name.id1 = c("0", "0", "0", 
    "0", "0", "0"), RNA_expression.id1 = c("0", "0", "0", "0", 
    "0", "0"), seqnames2 = c("chr1", "chr1", "chr1", "chr1", 
    "chr1", "chr1"), start2 = c(1886952L, 2562429L, 2908853L, 
    3596298L, 4008510L, 4025732L), end2 = c(1887558L, 2562819L, 
    2909055L, 3597281L, 4008863L, 4026507L), width2 = c(607L, 
    391L, 203L, 984L, 354L, 776L), strand2 = c("*", "*", "*", 
    "*", "*", "*"), node.class2 = c("intron", "exon", "intergenic_region", 
    "intron", "promoter_flanking_region", "promoter_flanking_region"
    ), promoter.id2 = c(0L, 0L, 0L, 0L, 0L, 0L), promoter_flanking_region.id2 = c(0L, 
    0L, 0L, 0L, 1L, 1L), exon.id2 = c(0L, 1L, 0L, 0L, 0L, 0L), 
    intron.id2 = c(1L, 0L, 0L, 1L, 1L, 0L), enhancer.id2 = c(0L, 
    1L, 0L, 0L, 0L, 0L), fli1.id2 = c(0L, 0L, 0L, 0L, 0L, 0L), 
    gata1.id2 = c(0L, 0L, 0L, 0L, 0L, 0L), gata2.id2 = c(0L, 
    0L, 0L, 0L, 0L, 0L), tal1.id2 = c(0L, 0L, 0L, 0L, 0L, 0L), 
    ctcf.id2 = c(0L, 1L, 0L, 0L, 0L, 0L), bait.id2 = c("0", "0", 
    "0", "0", "0", "0"), gene_name.id2 = c("GNB1_21665", "TNFRSF14_25838", 
    "0", "MEGF6_34434", "AL805961.1_25459", "0"), RNA_expression.id2 = c("0", 
    "0", "0", "0", "0", "0"), counts = c(0L, 1L, 1L, 3L, 3L, 
    3L), CHiCAGO_Score = c(0.57, 1.39, 1.78, 3.26, 3.52, 3.48
    ), distance_bait_prey = c(2320526, 1645157, 1298827, 610991, 
    199094, 181661), RNA_expression_gene_symbol_id1 = c(0, 0, 
    0, 0, 0, 0), RNA_expression_logFPKM_id1 = c(0, 0, 0, 0, 0, 
    0), RNA_expression_stratification_id1 = c(0, 0, 0, 0, 0, 
    0), RNA_expression_gene_symbol_id2 = c(0, 0, 0, 0, 0, 0), 
    RNA_expression_logFPKM_id2 = c(0, 0, 0, 0, 0, 0), RNA_expression_stratification_id2 = c(0, 
    0, 0, 0, 0, 0)), row.names = c(NA, -6L), class = c("data.table",  "data.frame"))

Мой (невоспроизводимый) код для импорта data.frame и начала новых столбцов с нуля

a <- data.table::fread(input='file',  sep = '\t', header = TRUE)
a$RNA_expression_gene_symbol_id1 <- "0"
a$RNA_expression_logFPKM_id1 <- "0"
a$RNA_expression_stratification_id1 <- "0"
a$RNA_expression_gene_symbol_id2 <- "0"
a$RNA_expression_logFPKM_id2 <- "0"
a$RNA_expression_stratification_id2 <- "0"

Цикл for, который я имел в виду

for ( i in seq(1, length(a$gene_name.id1))){
        if (a$RNA_expression.id1[i] != 0){
                b <- str_split(a$RNA_expression.id1[i], "_", n=3)
                a$RNA_expression_gene_symbol_id1[i] <- b[[1]][1]
                a$RNA_expression_logFPKM_id1[i] <- b[[1]][2]
                a$RNA_expression_stratification_id1[i] <- b[[1]][3]
                }
        if (a$RNA_expression.id2[i] != 0){
                b <- str_split(a$RNA_expression.id1[i], "_", n=3)
                a$RNA_expression_gene_symbol_id1[i] <- b[[1]][1]
                a$RNA_expression_logFPKM_id1[i] <- b[[1]][2]
               a$RNA_expression_stratification_id1[i] <- b[[1]][3]
                }
}

Я попытался создать функцию для использования apply() следующим образом:

my_function <- function(a){
        if (a[19] != 0){
                b <- str_split(a[19], "_", n=3)
                a[43] <- b[[1]][1]
                a[44] <- b[[1]][2]
                a[45] <- b[[1]][3]
                }
        if (a[19] != 0){
               b <- str_split(a[38], "_", n=3)
                a[46] <- b[[1]][1]
                a[47] <- b[[1]][2]
                a[48] <- b[[1]][3]
                }
}`

apply(a, 1, my_function)

Я получаю список NULL значений и только последнее из трех значений, которые я разделяю Где я не прав? я полностью не согласен со структурой сценария?

1 Ответ

1 голос
/ 28 июня 2019

Основная проблема заключается в том, что apply ожидает матрицу в качестве входных данных, так как вы предоставляете data.frame. Первое, что делает apply, - это приведение вашего data.frame в соответствие, следовательно, изменение всех столбцов на один и тот же тип и создание помехи.все.Другая проблема состоит в том, что apply возвращает массив или список значений, которые не являются ожидаемым выводом (data.frame / data.table).

Вы можете достичь того же результата с помощью separate из tidyr.Например, случай id1:

  separate(a,
           RNA_expression.id1, 
           into = c("RNA_expression_gene_symbol_id1", 
                    "RNA_expression_logFPKM_id1",
                    "RNA_expression_stratification_id1"), 
           sep = "_",
           fill = "left")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...