Выберите строки на основе комбинации сопоставленных и несоответствующих столбцов - PullRequest
0 голосов
/ 31 октября 2018

У меня есть такая таблица:

 data <- data.frame(a = c("0/0", "0/1", "0/0", "0/0" ),
                    b = c("0/1", "./.", "0/1", "0/0"),
                    c = c("1/0", "0/0", "1/1", "0/0"),
                    d = c("1/0", "0/0", "1/1", "0/0"),                       
                    f = c("L", "L", "T", "L"))

Я хотел бы выбрать любую строку, которая содержит хотя бы одну 0/1 или 1/0 и нет ./. в столбцах a, b и c, и которые соответствуют L в столбце f.

Я пытаюсь использовать библиотеку data.table

data[data$a %like% "0/1|1/0" | data$b %like% "0/1|1/0"| data$c %like% "0/1|1/0" & !(data$a %like% "./.") & !(data$b %like% "./.") & !(data$c %like% "./.") & data$f == "L", ]

Но это не работает.

Таблица выглядит так:

       a   b   c   d   f
    1 0/0 0/1 1/0 1/0  L
    2 0/1 ./. 0/0 0/0  L
    3 0/0 0/1 1/1 1/1  T
    4 0/0 0/0 0/0 0/0  L

И желаемый результат должен выглядеть так:

       a   b   c   d   f
    1 0/0 0/1 1/0 1/0  L

Вы знаете, как мне этого добиться?

Ответы [ 6 ]

0 голосов
/ 31 октября 2018

Вы можете сначала объединить столбцы a, b, c и d вместе.

data[, abcd := paste(a, b, c, d)]

Затем я бы создал еще один новый столбец, в котором будет указано, выполняются ли условия. Сначала я установил его на все FALSE.

data[, Selection := F]

Далее, только для столбцов, которые соответствуют условиям, присваивается TRUE.

(1) с "0/1" или "1/0" в a, b, c или d, или просто abcd

(2) не имеет "./." in abcd

(3) с "L" в столбце f

data[(grepl("0/1", abcd) | grepl("1/0", abcd)) & !grepl("\\./\\.", abcd) &
     f == "L",
     Selection := T]

Здесь я могу выбрать строку (и), необходимую для

data[(Selection), ]
0 голосов
/ 31 октября 2018

Вот простое решение с использованием apply из базы R -

test <- apply(data, 1, function(x) {
  any(x %in% c("0/1", "1/0")) & !any(x == "./.") & x["f"] == "L"
})

data[test, ]

#     a   b   c   d f
# 1 0/0 0/1 1/0 1/0 L
0 голосов
/ 31 октября 2018

Другой вариант:

data[f=="L", .SD[apply((.SD=="1/0" | .SD=="0/1") & !apply(.SD=="./.",1,any), 1, any)], 
    .SDcols=c("a","b","c","d")]
0 голосов
/ 31 октября 2018
data[ apply(sapply(data[1:4], `%in%`, c('0/1','1/0')), 1, any) &
      apply(sapply(data[1:3], Negate(`%in%`), c('./.')), 1, all) &
      data$f == "L", ]
#     a   b   c   d f
# 1 0/0 0/1 1/0 1/0 L

Сломано:

sapply(data[1:4], `%in%`, c('0/1','1/0'))
#          a     b     c     d
# [1,] FALSE  TRUE  TRUE  TRUE
# [2,]  TRUE FALSE FALSE FALSE
# [3,] FALSE  TRUE FALSE FALSE
# [4,] FALSE FALSE FALSE FALSE

Это дает нам экземпляры в первых четырех столбцах с одним из двух "требуемых" шаблонов. Нам нужны строки, в которых любые столбцов имеют его, поэтому мы "любые" по ним:

apply(sapply(data[1:4], `%in%`, c('0/1','1/0')), 1, any)
# [1]  TRUE  TRUE  TRUE FALSE

Аналогичным образом найдите тех, у кого есть паттерны «не нужны»:

sapply(data[1:3], Negate(`%in%`), c('./.'))
#         a     b    c
# [1,] TRUE  TRUE TRUE
# [2,] TRUE FALSE TRUE
# [3,] TRUE  TRUE TRUE
# [4,] TRUE  TRUE TRUE
apply(sapply(data[1:3], Negate(`%in%`), c('./.')), 1, all) # notice "all", not "any"
# [1]  TRUE FALSE  TRUE  TRUE

Теперь мы хотим, чтобы «L» в последнем столбце (=="L"), прямо, чтобы логически связать их с помощью &.

0 голосов
/ 31 октября 2018

Аналогично предыдущему ответу:

apply(data[, 1:4], 1, function(a) any(a %in% c("0/1","1/0")) && !any(a[1:3] == "./.")) & data$f == "L"
0 голосов
/ 31 октября 2018

Это ни в коем случае не быстрее, чем работающее решение data.table, но это работает с базой R:

dat <- data.frame(a = c("0/0", "0/1", "0/0", "0/0" ),
                   b = c("0/1", "./.", "0/1", "0/0"),
                   c = c("1/0", "0/0", "1/1", "0/0"),
                   d = c("1/0", "0/0", "1/1", "0/0"),                       
                   f = c("L", "L", "T", "L"))

dat
f <- which(colnames(dat) == 'f')
rows <- apply(dat, 1, function(x)  x[f] == "L" & !any("./." == x[-f]) & any("0/1" == x[-f]) | any("1/0" == x[-f]) )
dat[rows,]

Использует функцию apply для применения функции к строке данных.

...