Числа в 'возвращенном' являются результатом приведения factor
к значениям режима хранения integer
. Этого можно избежать, если мы создадим столбец класса character
с stringsAsFactors = FALSE
при создании data.frame или используем as.character(name)
.
d <- data.frame(name=c("Roy","Tom", "Pat"), stringsAsFactors = FALSE)
words <- data.frame(people=c("Mike", "Tom", "Molly", "Susan"),
dogs=c("Rex", "Fido", "King", "Roy"), stringsAsFactors = FALSE)
В дополнение к проблеме с factor
, код OP в ifelse
не использует набор данных keyvalue 'words', т.е. name %in% d
относится к вызову значения столбца 'name' в data.frame, а второй аргумент - colnames()
, что привело бы к «ошибке», но поскольку первое выражение возвращает FALSE
, оно проверит значения «no», т. е. «name»
d %>%
mutate(i1 = name %in% d)
# name i1
#1 Roy FALSE
#2 Tom FALSE
#3 Pat FALSE
Поскольку 'name' равно factor
, его значения приводятся к целочисленному режиму, и это то, что отображается в выходных данных
Мы можем использовать pivot_longer
для преобразования в 'long' формат, а затем сделать right_join
library(dplyr)
library(tidyr)
words %>%
pivot_longer(everything()) %>%
right_join(d, by = c('value' = 'name')) %>%
mutate(name = ifelse(is.na(name), value, name)) %>%
select(returned = name, name = value)
# returned name
#1 dogs Roy
#2 people Tom
#3 Pat Pat
Или мы можем использовать case_when
без какого-либо изменения
d %>%
mutate(returned = case_when(name %in% words$people ~ 'people',
name %in% words$dogs ~ 'dogs',
TRUE ~ as.character(name)))
# name returned
#1 Roy dogs
#2 Tom people
#3 Pat Pat
Или используя только base R
d$returned <- with(stack(words), as.character(ind[match(d$name, values)]))
d$returned[is.na(d$returned)] <- d$name[is.na(d$returned)]
d
# name returned
#1 Roy dogs
#2 Tom people
#3 Pat Pat