Как я могу создать столбец в моем фрейме данных, который отображается в список в R? - PullRequest
1 голос
/ 06 июня 2019

У меня есть некоторые лицензионные данные, и я пытаюсь создать столбец в моем фрейме данных, который сообщает мне, является ли указанная лицензия приемлемой, основываясь на программе, в которую кто-то зарегистрирован.

Для этого я создал список, так как некоторые лицензии приемлемы для более чем одной программы. В идеале я думал о том, что я мог бы каким-то образом использовать этот список в качестве ссылки, чтобы увидеть, была ли программа указана под названием лицензии. Я также пробовал case_when, но продолжал получать ошибки. Я также предпочел бы иметь список, который я могу использовать в качестве карты, потому что названия лицензий, вероятно, будут меняться из года в год.

Пример кода

Ниже приведен фрагмент моего фрейма данных:

df1 <- data.frame(Program = c("Elementary Education", "Elementary Education", "Secondary Math", "Secondary Math", "Secondary ELA", "Secondary ELA"), Licensure = c("Content Area - Elementary Education (Grades 1-6)", "Content Area - Secondary Math (Grades 7-12)", "Content Area - Secondary Math (Grades 7-12)", "Mathematics (Grades 7-12) 1706", "Content Area - Secondary ELA (Grades 7-12)", "Content Area - Early Childhood (preK-Grade 3)"))

Вот список, который я создал, который включает все лицензии с допустимыми программами под каждым:

license_index <- list(
  "Content Area - Early Childhood (preK-Grade 3)" = "Elementary Education",
  "Content Area - Elementary Education (Grades 1-6)" = "Elementary Education",
  "Content Area - Middle Grades ELA (Grades 4-9)" = c("Elementary Education", "Secondary ELA"),
  "Content Area - Middle Grades Math (Grades 4-9)" = c("Elementary Education", "Secondary Math"),
  "Content Area - Middle School Mathematics (Grades 4-8)" = "Elementary Education",
  "Content Area - Secondary ELA (Grades 7-12)" = "Secondary ELA",
  "Content Area - Secondary Math (Grades 7-12)" = "Secondary Math",
  "Content Area - Secondary English (Grades 7-12)" = "Secondary ELA",
  "English Language Arts and Reading (Grades 4-8) 864" = "Elementary Education",
  "Core Subjects (Grades EC-6) 1770" = "Elementary Education",
  "English Language Arts and Reading (Grades 7-12) 1709" = "Secondary ELA",
  "Mathematics (Grades 4-8) 866" = "Elementary Education",
  "Mathematics (Grades 7-12) 1706" = "Secondary Math"
)

В идеале, в идеале, мне бы хотелось, чтобы лицензия и программа совпадали или нет:

ideal.df <- data.frame(Program = c("Elementary Education", "Elementary Education", "Secondary Math", "Secondary Math", "Secondary ELA", "Secondary ELA"), Licensure = c("Content Area - Elementary Education (Grades 1-6)", "Content Area - Secondary Math (Grades 7-12)", "Content Area - Secondary Math (Grades 7-12)", "Mathematics (Grades 7-12) 1706", "Content Area - Secondary ELA (Grades 7-12)", "Content Area - Early Childhood (preK-Grade 3)"), match = c("Match", "No", "Match", "Match", "Match", "No"))

Я думаю, что мне нужна функция mutate и, возможно, я использую функцию карты purrr, но я не очень знаком с tidyverse и буду очень признателен за помощь! Заранее спасибо!

Ответы [ 3 ]

4 голосов
/ 06 июня 2019

Попробуйте это:

x<-stack(license_index)
x$values[match(df1$Licensure,x$ind)]==df1$Program
#[1]  TRUE FALSE  TRUE  TRUE  TRUE FALSE

Вы можете сопоставить значения TRUE и FALSE вышеупомянутых с Match и No, если необходимо.

2 голосов
/ 06 июня 2019

Вот один из способов с tidyverse, где мы преобразуем именованный list в двухстоечный файл data.frame с enframe, right_join с исходным набором данных и создаем match, сравнивая совпадение столбца'with' Program '

library(tidyverse)
enframe(license_index, name = "Licensure", value = "match") %>%
    unnest %>% 
    right_join(df1) %>% 
    mutate(match = match == Program) %>%
    select(names(df1), everything())
# A tibble: 6 x 3
#  Program              Licensure                                        match
#  <fct>                <chr>                                            <lgl>
#1 Elementary Education Content Area - Elementary Education (Grades 1-6) TRUE 
#2 Elementary Education Content Area - Secondary Math (Grades 7-12)      FALSE
#3 Secondary Math       Content Area - Secondary Math (Grades 7-12)      TRUE 
#4 Secondary Math       Mathematics (Grades 7-12) 1706                   TRUE 
#5 Secondary ELA        Content Area - Secondary ELA (Grades 7-12)       TRUE 
#6 Secondary ELA        Content Area - Early Childhood (preK-Grade 3)    FALSE

Или мы можем использовать пакет rap , который может быть полезен для этого сценария

library(rap)
df1 %>% 
   rap(match = ~ license_index[[as.character(Licensure)]] == Program) %>%
   unnest
#              Program                                        Licensure match
#1 Elementary Education Content Area - Elementary Education (Grades 1-6)  TRUE
#2 Elementary Education      Content Area - Secondary Math (Grades 7-12) FALSE
#3       Secondary Math      Content Area - Secondary Math (Grades 7-12)  TRUE
#4       Secondary Math                   Mathematics (Grades 7-12) 1706  TRUE
#5        Secondary ELA       Content Area - Secondary ELA (Grades 7-12)  TRUE
#6        Secondary ELA    Content Area - Early Childhood (preK-Grade 3) FALSE
0 голосов
/ 06 июня 2019

Я не могу вам помочь с Tidyverse, но это решение base-R должно работать:

df1$match <-sapply(1:nrow(df1), function(i){
  ifelse(license_index[[which(names(license_index) == df1$Licensure[i])]] == df1$Program[i],'Match','No')})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...