У меня возникли проблемы с сопоставлением шаблонов в фрейме данных. Я работаю с функцией grepl в R.
У меня есть набор данных по 5 местным районам за два года (2001 и 2002 гг.). Я хочу проверить, совпадают ли правящая партия(и) округа с правящей партией(ями) на национальном уровне.
Моя модель должна предполагать, что существует согласие, когда хотя бы одна из правящих партий страны также правит на уровне округа.
Мои исходные данные выглядят так
df.1 <- data.frame(district= rep(c(1000:1004), times=2),
district.party= rep(c("PartyA-PartyB", "PartyA", "PartyB", "PartyC", "PartyA-PartyC"), times=2),
year= rep(2000:2001, each=5),
national.party= rep(c("PartyA|PartyB", "PartyA"), each=5))
> df.1
district district.party year national.party
1 1000 PartyA-PartyB 2000 PartyA|PartyB
2 1001 PartyA 2000 PartyA|PartyB
3 1002 PartyB 2000 PartyA|PartyB
4 1003 PartyC 2000 PartyA|PartyB
5 1004 PartyA-PartyC 2000 PartyA|PartyB
6 1000 PartyA-PartyB 2001 PartyA
7 1001 PartyA 2001 PartyA
8 1002 PartyB 2001 PartyA
9 1003 PartyC 2001 PartyA
10 1004 PartyA-PartyC 2001 PartyA
В идеале я хочу, чтобы мой новый фрейм данных выглядел так:
df.1.neat <- data.frame(district= rep(c(1000:1004), times=2),
district.party= rep(c("PartyA-PartyB", "PartyA", "PartyB", "PartyC", "PartyA-PartyC"), times=2),
year= rep(2000:2001, each=5),
national.party= rep(c("PartyA|PartyB", "PartyA"), each=5),
alignment= c("TRUE", "TRUE", "TRUE", "FALSE", "TRUE", "TRUE", "TRUE", "FALSE", "FALSE", "TRUE"))
> df.1.neat
district district.party year national.party alignment
1 1000 PartyA-PartyB 2000 PartyA|PartyB TRUE
2 1001 PartyA 2000 PartyA|PartyB TRUE
3 1002 PartyB 2000 PartyA|PartyB TRUE
4 1003 PartyC 2000 PartyA|PartyB FALSE
5 1004 PartyA-PartyC 2000 PartyA|PartyB TRUE
6 1000 PartyA-PartyB 2001 PartyA TRUE
7 1001 PartyA 2001 PartyA TRUE
8 1002 PartyB 2001 PartyA FALSE
9 1003 PartyC 2001 PartyA FALSE
10 1004 PartyA-PartyC 2001 PartyA TRUE
Я использую grepl и dplyr
df.1.neat.OP <- df.1 %>%
mutate(alignment= grepl(national.coalition, county.party))
> df.1.neat.OP
district county.party year national.coalition alignment
1 1000 PartyA-PartyB 2000 PartyA|PartyB TRUE
2 1001 PartyA 2000 PartyA|PartyB TRUE
3 1002 PartyB 2000 PartyA|PartyB TRUE
4 1003 PartyC 2000 PartyA|PartyB FALSE
5 1004 PartyA-PartyC 2000 PartyA|PartyB TRUE
6 1000 PartyA-PartyB 2001 PartyA TRUE
7 1001 PartyA 2001 PartyA TRUE
8 1002 PartyB 2001 PartyA TRUE
9 1003 PartyC 2001 PartyA FALSE
10 1004 PartyA-PartyC 2001 PartyA TRUE
Обратите внимание, что моя команда хорошо работает для 2000 года, но вычисляет неправильный результат для округа 1002 в 2001 году. В моем более широком массиве данных имеется множество подобных ошибок.
какие-либо предложения?
@AdamO, в этом особом случае ты можешь ошибаться, например. | обычно обозначает ИЛИ, как вы наверняка знаете. / и + могут подойти лучше.
@Фриде, пожалуйста, читай внимательнее. Нередко используется канал в качестве вторичного разделителя в извлечениях базы данных, например. Microsoft Access или RedHat. Что еще более важно, вы должны посмотреть на второй столбец. Ни один из них не использует / или +.
В данном случае | — это оператор ИЛИ.





grepl() — неподходящая функция для данного варианта использования. Нативное решение tidyverse с использованием stringr::str_dectect():
library(dplyr)
library(stringr)
df.1 <- data.frame(district = rep(c(1000:1004), times=2),
district.party = rep(c("PartyA-PartyB", "PartyA", "PartyB", "PartyC", "PartyA-PartyC"), times=2),
year = rep(2000:2001, each=5),
national.party = rep(c("PartyA|PartyB", "PartyA"), each=5))
df.1.neat <- df.1 %>%
mutate(alignment = str_detect(district.party, national.party))
df.1.neat
# district district.party year national.party alignment
# 1 1000 PartyA-PartyB 2000 PartyA|PartyB TRUE
# 2 1001 PartyA 2000 PartyA|PartyB TRUE
# 3 1002 PartyB 2000 PartyA|PartyB TRUE
# 4 1003 PartyC 2000 PartyA|PartyB FALSE
# 5 1004 PartyA-PartyC 2000 PartyA|PartyB TRUE
# 6 1000 PartyA-PartyB 2001 PartyA TRUE
# 7 1001 PartyA 2001 PartyA TRUE
# 8 1002 PartyB 2001 PartyA FALSE
# 9 1003 PartyC 2001 PartyA FALSE
# 10 1004 PartyA-PartyC 2001 PartyA TRUE
или чтобы grepl() работало:
df.1.neat <- df.1 |>
rowwise() |>
mutate(alignment = grepl(national.party, district.party)) |>
ungroup()
Простой подход на базе R
> unname(Vectorize(grepl)(pattern=df.1$national.party, x=df.1$district.party))
[1] TRUE TRUE TRUE FALSE TRUE TRUE TRUE FALSE FALSE TRUE
Указывает ли
PartyA-PartyCдиапазон, другими словами, еслиcounty.party— этоPartyA-PartyC, аnational.coalition— этоPartyB. Они выровнены?