Выбирать строки на основе сочетания совпадающих и несоответствующих столбцов

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

 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[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

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

Если один из ответов касается вашего вопроса, пожалуйста, принять это; это не только дает некоторую льготу отвечающему на некоторые вопросы, но также дает некоторое завершение для читателей, задающих аналогичные вопросы. Хотя вы можете принять только один ответ, у вас есть возможность проголосовать столько, сколько вы считаете полезными. (Если по-прежнему возникают проблемы, вам, вероятно, придется отредактировать свой вопрос, указав более подробную информацию.)

r2evans 31.10.2018 16:27
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
52
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Это ни в коем случае не быстрее, чем рабочее решение 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(data[, 1:4], 1, function(a) any(a %in% c("0/1","1/0")) && !any(a[1:3] == "./.")) & data$f == "L"
Ответ принят как подходящий
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"), чтобы напрямую связать их логически с &.

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

data[f= = "L", .SD[apply((.SD= = "1/0" | .SD= = "0/1") & !apply(.SD= = "./.",1,any), 1, any)], 
    .SDcols=c("a","b","c","d")]

Вот простое решение с использованием 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/1» в f или «./.» в d.

Kamil Bartoń 31.10.2018 11:29

Сначала вы можете объединить столбцы 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) отсутствие "./." в abcd

(3) наличие "L" в столбце f

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

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

data[(Selection), ]

Другие вопросы по теме