Есть ли функция R или функция dplyr, где вы можете присваивать значения без замены? - PullRequest
0 голосов
/ 11 апреля 2020

Например, если у меня есть фрейм данных:

v1 v2
a  1 
b  2 
c  3 
a  1
c  3

Я хочу создать v3, если v1 равно их соответствующим значениям. Например, если v1 равно a, то я хочу присвоить v3 «науку», а если v1 равно b, то я хочу присвоить v3 «математика» и т. Д. c.

v1 v2 v3
a  1  science
b  2  maths
c  3  english
a  1  science
c  3  english

Я бы сделал это стандартным способом, перечислив множество условий, используя dplyr case_when или recode, но в переменной слишком много уникальных значений, которые я применяю для эффективного выполнения условия.

Спасибо.

Ответы [ 3 ]

0 голосов
/ 11 апреля 2020

Вы можете использовать встроенную функцию merge () для достижения этой цели. Работает больше как соединение в sql. Ниже приведен пример

df1 <- data.frame(v1=c("a","b","c","a","e"),v2=c(1,2,3,4,5))
df2 <- data.frame(c1=c("a","b","c","d","e"),c2=c("maths","mechanics","biology","chemistry","physics"))

df3 <- merge(df1,df2,by.x='v1',by.y='c1',all.x = TRUE)

#INPUT
#df1
# v1 v2
# 1  a  1
# 2  b  2
# 3  c  3
# 4  a  4
# 5  e  5

#df2
# c1        c2
# 1  a     maths
# 2  b mechanics
# 3  c   biology
# 4  d chemistry
# 5  e   physics

#df3
# v1 v2        c2
# 1  a  1     maths
# 2  a  4     maths
# 3  b  2 mechanics
# 4  c  3   biology
# 5  e  5   physics
0 голосов
/ 11 апреля 2020

Ваш вопрос немного двусмысленный, но вы, похоже, хотите сопоставить буквы с эквивалентным числом в алфавите. В этом случае вы можете создать factor уровни, числовое значение которых соответствует его letters.

.labels <- c("science", "maths", "english")
dat$v3 <- factor(with(dat, ifelse(v1 == letters[v2], v2, NA)), 
                 labels=.labels)
#   v1 v2      v3
# 1  a  1 science
# 2  b  2   maths
# 3  c  3 english
# 4  a  1 science
# 5  b  4    <NA>
# 6  c  3 english

Данные

dat <- structure(list(v1 = c("a", "b", "c", "a", "b", "c"), v2 = c(1L, 
2L, 3L, 1L, 4L, 3L)), row.names = c(NA, -6L), class = "data.frame")
0 голосов
/ 11 апреля 2020

Вы можете использовать case_when:

library(dplyr)

df %>%
 mutate(v3 = case_when(v1 == 'a' ~ 'science',
                       v1 == 'b' ~ 'maths', 
                       v1 == 'c' ~ 'english'))

#  v1 v2      v3
#1  a  1 science
#2  b  2   maths
#3  c  3 English
#4  a  1 science
#5  c  3 english

Или создать ссылочный фрейм данных и использовать merge:

ref_df <- data.frame(v1 = c('a', 'b', 'c'),v3 = c('science', 'maths', 'english'), 
                     stringsAsFactors = FALSE)

merge(df, ref_df, by = 'v1')

data

df <- structure(list(v1 = structure(c(1L, 2L, 3L, 1L, 3L), .Label = c("a", 
"b", "c"), class = "factor"), v2 = c(1L, 2L, 3L, 1L, 3L)), 
class = "data.frame", row.names = c(NA, -5L))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...