#r
#r
Вопрос:
У меня есть фрейм данных, подобный приведенному ниже, имеющий name
и email
столбец.
df <- data.frame(name=c("maay,bhtr","nsgu,nhuts thang","affat,nurfs","nukhyu,biyts","ngyst,muun","nsgyu,noon","utrs guus,book","thum,cryant","mumt,cant","bhan,btan","khtri,ntuk","ghaan,rstu","shaan,btqaan","nhue,bjtraan","wutys,cyun","hrtsh,jaan"),
email=c("maay.bhtr@email.com","nsgu.nhuts@gmail.com","asfa.1234@gmail.com","nukhyu.biyts@gmail.com","ngyst.muun@gmail.com","nsgyu.noon@gmail.com","utrs.book@hotmail.com","thum.cryant@live.com","mumt.cant@gmail.com","bhan.btan@gmail.com","khtri.ntuk@gmail.c.om","chang.lee@gmail.com","shaan.btqaan@gmail.com","nhue.bjtraan@gmail.com","wutys.cyun@gmailcom","hrtsh.jaan@gmail.com"))
Я ищу функцию, с помощью которой я могу проверить, совпадает ли имя или фамилия с идентификатором почты, а затем изменить новый столбец на true.
Ответ №1:
В Base R
мы можем использовать Map()
и sapply()
для перебора вашего списка и создания логического вектора для последующего добавления в ваш df:
Поскольку этот код включал множество вложенных операторов apply, позвольте мне попытаться объяснить, что происходит. Код, вероятно, лучше всего понять, если начать изнутри.
# t is the strsplit() names column
strsplit(df[,1], ",")
# this next line checks if the names occur in the email address
grepl(t, y, fixed = T)
# this statement wrapped in sapply returns a list with each entry containing two true/false statements for first and last name
# the sapply() statement above allows us to do exactly that for every row
# lastly we convert this list into a single true/false for each df entry
Код:
a <- sapply(Map(function(x, y){
sapply(x, function(t){
grepl(t, y, fixed = T)
})}
, strsplit(df[,1], ","), df[, 2]), function(p){
if(any(p)){
T
} else {
F
}
})
# result
cbind(df, a)
name email a
1 maay,bhtr maay.bhtr@email.com TRUE
2 nsgu,nhuts thang nsgu.nhuts@gmail.com TRUE
3 affat,nurfs asfa.1234@gmail.com FALSE
4 nukhyu,biyts nukhyu.biyts@gmail.com TRUE
5 ngyst,muun ngyst.muun@gmail.com TRUE
6 nsgyu,noon nsgyu.noon@gmail.com TRUE
7 utrs guus,book utrs.book@hotmail.com TRUE
8 thum,cryant thum.cryant@live.com TRUE
9 mumt,cant mumt.cant@gmail.com TRUE
10 bhan,btan bhan.btan@gmail.com TRUE
11 khtri,ntuk khtri.ntuk@gmail.c.om TRUE
12 ghaan,rstu chang.lee@gmail.com FALSE
13 shaan,btqaan shaan.btqaan@gmail.com TRUE
14 nhue,bjtraan nhue.bjtraan@gmail.com TRUE
15 wutys,cyun wutys.cyun@gmailcom TRUE
16 hrtsh,jaan hrtsh.jaan@gmail.com TRUE
Ответ №2:
Может быть, вы можете попробовать
within(
df,
consistent <- mapply(
function(x, y) 1 - any(mapply(grepl, x, y) | mapply(grepl, x, y)),
strsplit(name, ","),
strsplit(gsub("@.*", "", email), "\.")
)
)
что дает
name email consistent
1 maay,bhtr maay.bhtr@email.com 0
2 nsgu,nhuts thang nsgu.nhuts@gmail.com 0
3 affat,nurfs asfa.1234@gmail.com 1
4 nukhyu,biyts nukhyu.biyts@gmail.com 0
5 ngyst,muun ngyst.muun@gmail.com 0
6 nsgyu,noon nsgyu.noon@gmail.com 0
7 utrs guus,book utrs.book@hotmail.com 0
8 thum,cryant thum.cryant@live.com 0
9 mumt,cant mumt.cant@gmail.com 0
10 bhan,btan bhan.btan@gmail.com 0
11 khtri,ntuk khtri.ntuk@gmail.c.om 0
12 ghaan,rstu chang.lee@gmail.com 1
13 shaan,btqaan shaan.btqaan@gmail.com 0
14 nhue,bjtraan nhue.bjtraan@gmail.com 0
15 wutys,cyun wutys.cyun@gmailcom 0
16 hrtsh,jaan hrtsh.jaan@gmail.com 0
Ответ №3:
Вы могли бы сделать это следующим образом — код прокомментирован ниже.
df <- data.frame(name=c("maay,bhtr","nsgu,nhuts thang","affat,nurfs","nukhyu,biyts","ngyst,muun","nsgyu,noon","utrs guus,book","thum,cryant","mumt,cant","bhan,btan","khtri,ntuk","ghaan,rstu","shaan,btqaan","nhue,bjtraan","wutys,cyun","hrtsh,jaan"),
email=c("maay.bhtr@email.com","nsgu.nhuts thang@gmail.com","asfa.1234@gmail.com","nukhyu.biyts@gmail.com","ngyst.muun@gmail.com","nsgyu.noon@gmail.com","utrs guus.book@hotmail.com","thum.cryant@live.com","mumt.cant@gmail.com","bhan.btan@gmail.com","khtri.ntuk@gmail.c.om","chang.lee@gmail.com","shaan.btqaan@gmail.com","nhue.bjtraan@gmail.com","wutys.cyun@gmailcom","hrtsh.jaan@gmail.com"))
library(stringr)
library(dplyr)
## extract all of the names any string of letters unbroken by a space or punctuation or number
names <- str_extract_all(df$name, "[A-Za-z]*") %>%
## make a matrix out of the names
do.call(rbind, .) %>%
## turn the names into a data frame
as.data.frame()
## some of the columns have all "" in them, find which ones are all ""
w <- sapply(names, function(x)all(x == ""))
## if any of the columns are all "" then ...
if(any(w)){
## remove those columns from the dataset
names <- names[,-which(w)]
}
## add email into this dataset that has the individual names
names$email <- df$email
library(tidyr)
## pipe the names dataset (which has individual names and an e-mail address)
out <- names %>%
## switch from wide to long format
pivot_longer(-email, names_to="V", values_to="n") %>%
## create consistent = 1 if the name is not detected in the e-mail
mutate(consistent = !str_detect(email, n)) %>%
## group the data by e-mail
group_by(email) %>%
## take the maximum of consistent by group
## this will be 1 if any of the names are not detected in the e-mail
summarise(consistent = max(consistent)) %>%
## join back together with the original data
left_join(df) %>%
## change the variable ordering back
select(name, email, consistent)
out
# # A tibble: 16 x 3
# name email consistent
# <chr> <chr> <int>
# 1 affat,nurfs asfa.1234@gmail.com 1
# 2 bhan,btan bhan.btan@gmail.com 0
# 3 ghaan,rstu chang.lee@gmail.com 1
# 4 hrtsh,jaan hrtsh.jaan@gmail.com 0
# 5 khtri,ntuk khtri.ntuk@gmail.c.om 0
# 6 maay,bhtr maay.bhtr@email.com 0
# 7 mumt,cant mumt.cant@gmail.com 0
# 8 ngyst,muun ngyst.muun@gmail.com 0
# 9 nhue,bjtraan nhue.bjtraan@gmail.com 0
# 10 nsgu,nhuts thang nsgu.nhuts thang@gmail.com 0
# 11 nsgyu,noon nsgyu.noon@gmail.com 0
# 12 nukhyu,biyts nukhyu.biyts@gmail.com 0
# 13 shaan,btqaan shaan.btqaan@gmail.com 0
# 14 thum,cryant thum.cryant@live.com 0
# 15 utrs guus,book utrs guus.book@hotmail.com 0
# 16 wutys,cyun wutys.cyun@gmailcom 0
#
Обратите внимание, мне пришлось изменить два значения электронной почты в вашем наборе данных, чтобы они соответствовали размещенному вами изображению.