Поиск строк фрейма данных, которые содержат определенный символ только один раз - PullRequest
1 голос
/ 15 апреля 2020

Извините за возможное дублирование, но я не знаю, как сформулировать свой запрос. Я работаю над R и хотел бы иметь возможность идентифицировать ячейки фрейма данных, которые содержат определенный символ, только один раз.

В моем df есть столбец a, содержащий формулы, хранящиеся в виде строк, например

# a
1 y~x1+x2
2 y~x2+x3
3 y~x1+x2+x3
4 y~x2+x4
5 y~x1+x3+x4

и я хотел бы сохранить строки, формулы которых в столбце a имеют 2 объясняющие переменные, то есть содержащие только один "+". Идея состоит в том, чтобы отфильтровать и добавить тип манекена, например, результат будет выглядеть как

# a b
1 y~x1+x2 1
2 y~x2+x3 1
3 y~x1+x2+x3 0
4 y~x2+x4 1
5 y~x1+x3+x4 0

Надеюсь, это достаточно ясно. Спасибо за помощь,
Val

Ответы [ 3 ]

3 голосов
/ 15 апреля 2020

Вы можете использовать gsub с [^+], чтобы извлечь все + и nchar, чтобы получить их число.

x$b <- +(nchar(gsub("[^+]", "", x$a)) == 1)
x
#           a b
#1    y~x1+x2 1
#2    y~x2+x3 1
#3 y~x1+x2+x3 0
#4    y~x2+x4 1
#5 y~x1+x3+x4 0

Или использовать gregexpr:

lapply(gregexpr("\\+", x$a), length) == 1
#[1]  TRUE  TRUE FALSE  TRUE FALSE

Или используя его с lengths как предложено @ThomasIsCoding:

lengths(gregexpr("\\+", x$a)) == 1
#[1]  TRUE  TRUE FALSE  TRUE FALSE

Или используя grepl:

grepl("^[^+]*\\+[^+]*$", x$a)
#[1]  TRUE  TRUE FALSE  TRUE FALSE

Или с strsplit:

sapply(strsplit(x$a, ""), function(y) sum(y == "+")==1)
#[1]  TRUE  TRUE FALSE  TRUE FALSE

Данные:

x <- read.table(header=TRUE, text="a
1  y~x1+x2
2  y~x2+x3
3  y~x1+x2+x3
4  y~x2+x4
5  y~x1+x3+x4", stringsAsFactors = FALSE)
1 голос
/ 15 апреля 2020

Третья базовая альтернатива, при условии, что в формуле всегда есть как минимум два предиктора.

df$b <- +(!grepl("\\+.*\\+", df$a))

df
           a b
1    y~x1+x2 1
2    y~x2+x3 1
3 y~x1+x2+x3 0
4    y~x2+x4 1
5 y~x1+x3+x4 0
1 голос
/ 15 апреля 2020

Другое базовое решение R использует gregexpr, то есть

df$b <- +(lengths(gregexpr("\\+",df$a))==1)

, такое что

> df
           a b
1    y~x1+x2 1
2    y~x2+x3 1
3 y~x1+x2+x3 0
4    y~x2+x4 1
5 y~x1+x3+x4 0

DATA

df <- structure(list(a = c("y~x1+x2", "y~x2+x3", "y~x1+x2+x3", "y~x2+x4", 
"y~x1+x3+x4")), class = "data.frame", row.names = c("1", "2", 
"3", "4", "5"))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...