Проверьте, появляется ли строка в каком-либо столбце (кроме 1-го) таблицы данных

Основываясь на data.table, DT, с m строковыми столбцами, как можно пометить строки, в которых строка, скажем, «BlaBla», появляется хотя бы в одном столбце?

Я хочу:

DT[, flag_BlaBLa:=(test if "BlaBLa" appears in any column except the first one)]

Я не хочу делать явную ссылку на имена столбцов. Скорее мне нужно обратиться к столбцу 2 к максимальному номеру столбца в DT (возможно: 2:ncol(DT)). Почему бы нет? На самом деле у меня есть список data.frames с разным количеством столбцов в каждом. Мне нужно создать флаг, как указано выше, для всех data.frames в списке

Edit1: добавление воспроизводимого примера. Edit2: изменение некоторых строк «BlaBLa» на «BlaBLa + что-то». Это также должно считаться совпадением, поскольку они включают «BlaBLa».

DT начинается с столбцов a,b,c, и мне нужен скрипт для создания flag_BlaBLa. Конечным результатом будет:

DT <- data.table(a=c("x","y","z",'w'),
                 b=c('BlaBLa','BLe','Bli','BlaBLaSometing'), 
                 c=c('Bla','BLe','BlaBLa','Blo'), 
                 flag_BlaBLa=c(T,F,T,T)
                 )

Для списка окончательный результат должен быть:

DT1 <- data.table(a=c("x","y","z",'w'),
                 b=c('BlaBLa','BLe','Bli','BlaBLaSomething'), 
                 c=c('Bla','BLe','BlaBLa','Blo'), 
                 flag_BlaBLa=c(T,F,T,T)
                 )

DT2 <- data.table(a=c("q","j","p"),
                 b=c('BLe','Bli','BlaBLa'), 
                 flag_BlaBLa=c(F,F,T)
                 )
l <- list(DT1,DT2)

возможно, вы можете создать ключ всех значений столбца, объединенных некоторым разделителем, за исключением первого столбца. Затем найдите строку в ключе.

samkart 31.03.2019 09:43

@samkart, это хорошая идея. Но как я могу создать эту конкатенированную переменную без явного упоминания имен столбцов, только диапазон столбцов 2:ncol(DT)?

LucasMation 31.03.2019 09:45
DT[, key_ := do.call(paste, c(.SD, sep = "_")), .SDcols = 2:ncol(DT)]. Это может помочь вам в создании ключа, исключая первый столбец.
samkart 31.03.2019 09:48

@samkart, Ницца, спасибо. Это работает. Потом сделал DT[, flag_BlaBLa := key_ %>% str_detect('BlaBLa')] И получил правильный результат. Нет, мне нужно сделать эти два шага для каждого элемента списка l. Ты знаешь как? В любом случае, пожалуйста, добавьте ответ в эти два комментария в качестве ответа

LucasMation 31.03.2019 09:56

вы можете использовать цикл for для перебора списка l. for (DTbl in l){ code }

samkart 31.03.2019 10:05
Стоит ли изучать 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
5
291
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Мы могли бы перебрать список, выбрать столбцы и проверить, есть ли хотя бы один «BlaBLa» в любой строке, и отметить строку TRUE/FALSE.

library(data.table)
lapply(l, function(x) x[, flag_BlaBLa := rowSums(x[,2:ncol(x)] == "BlaBLa") > 0])


l
#[[1]]
#   a      b      c flag_BlaBLa
#1: x BlaBLa    Bla        TRUE
#2: y    BLe    BLe       FALSE
#3: z    Bli BlaBLa        TRUE
#4: w BlaBLa    Blo        TRUE

#[[2]]
#   a      b flag_BlaBLa
#1: q    BLe       FALSE
#2: j    Bli       FALSE
#3: p BlaBLa        TRUE

РЕДАКТИРОВАТЬ

Если это не точное совпадение, и нам нужно найти шаблон этой строки, нам также может понадобиться перебрать столбцы (аналогично @MichaelChirico), прежде чем принимать rowSums

lapply(l, function(x) x[, flag_BlaBLa := rowSums(sapply(x[, 2:ncol(x)],
                      grepl, pattern = 'BlaBLa', fixed = TRUE)) > 0])


#[[1]]
#   a               b      c flag_BlaBLa
#1: x          BlaBLa    Bla        TRUE
#2: y             BLe    BLe       FALSE
#3: z             Bli BlaBLa        TRUE
#4: w BlaBLaSomething    Blo        TRUE

#[[2]]
#   a      b flag_BlaBLa
#1: q    BLe       FALSE
#2: j    Bli       FALSE
#3: p BlaBLa        TRUE

это красиво и лаконично. Но переменные, которые я исследую, могут иметь больше, чем просто работу. "БлаБЛа" также учитывается (мой первоначальный пример должен был отразить эту возможность). Поэтому там, где в приведенном выше коде есть «==», должна быть какая-то форма регулярного выражения.

LucasMation 31.03.2019 10:29

Смотрите %like% оператор

jangorecki 31.03.2019 10:36

@LucasMation вы имеете в виду, что у вас могут быть другие варианты «BlaBLa» или других слов? Вы хотите точное совпадение разных слов или шаблонов совпадений?

Ronak Shah 31.03.2019 10:39

@RonakShah, «BlaBLa» должен быть частью строк. См. обновленный пример выше.

LucasMation 31.03.2019 19:45

@LucasMation Соответствующим образом обновил ответ.

Ronak Shah 01.04.2019 05:29

Вот подход с .SDcols

require(dplyr)
require(data.table)
require(stringr)

DT <- DT[, key_ := do.call(paste, c(.SD, sep = "_")), .SDcols = 2:ncol(DT)]
DT <- DT[, has_blabla := as.integer(str_detect(key_, "BlaBla"))]

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

Я бы использовал цикл for по списку и sapply по столбцам, используя .SDcols для исключения первого:

for (ii in seq_along(l)) {
  l[[ii]][ , .SDcols = -1L, 
          flag_BlaBLa := any(sapply(.SD, grepl, pattern = 'BlaBLa', fixed = TRUE))] 
}

Обратите внимание: поскольку вы на самом деле не используете какое-либо регулярное выражение, fixed = TRUE является более эффективным вариантом для использования grepl. Отбросьте fixed = TRUE, если шаблон, который вы пытаетесь обнаружить, действительно является регулярным выражением.

Если не все ваши столбцы являются строковыми столбцами, это можно сделать более эффективным, сделав .SDcols более строгим, например.

.SDcols = intersect(2:ncols(l[[ii]]), which(sapply(l[[ii]], is.character)))

(или, возможно, используя is.character(x) || is.factor(x))

Мы можем указать интересующие столбцы в .SDcols, пройтись по подмножеству data.table (.SD), проверить, равно ли оно «BlaBLa», Reduce в один логический vector, чтобы создать столбец

library(data.table)
lapply(l, function(x) x[, flag_BlaBLa := Reduce(`|`, lapply(.SD, `==`, 
           "BlaBLa")), .SDcols = 2:ncol(x)][])
#[[1]]
#   a      b      c flag_BlaBLa
#1: x BlaBLa    Bla        TRUE
#2: y    BLe    BLe       FALSE
#3: z    Bli BlaBLa        TRUE
#4: w BlaBLa    Blo        TRUE

#[[2]]
#   a      b flag_BlaBLa
#1: q    BLe       FALSE
#2: j    Bli       FALSE
#3: p BlaBLa        TRUE

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