Заполнение элементов строки заголовком столбца с учетом определенных критериев в R - PullRequest
1 голос
/ 17 марта 2020

У меня большой набор данных, состоящий из нескольких столбцов с именами состояний. Каждая строка состоит из индивида и того, в каком состоянии они проживают, и в столбце соответствующего состояния они обозначаются символом «да».

Name <- c("John", "Jane", "Joe", "Jim", "Jeane", "Jeff", "Jack")
Q1State1 <- c("no", "yes", "yes", "no", "no", "no", "no")
Q1State2 <- c("yes", "no", "no", "no", "no", "no", "yes")
Q1State3 <- c("no", "no", "no", "yes", "yes", "yes", "no")
Q2State1 <- c("no", "yes", "yes", "no", "no", "no", "no")
Q2State2 <- c("yes", "no", "no", "no", "no", "no", "yes")
Q2State3 <- c("no", "no", "no", "yes", "yes", "yes", "no")
DF <- data.frame(Name, Q1State1, Q1State2, Q1State3, Q2State1, Q2State2, Q2State3)

   Name Q1State1 Q1State2 Q1State3 Q2State1 Q2State2 Q2State3
1  John       no      yes       no       no      yes       no
2  Jane      yes       no       no      yes       no       no
3   Joe      yes       no       no      yes       no       no
4   Jim       no       no      yes       no       no      yes
5 Jeane       no       no      yes       no       no      yes
6  Jeff       no       no      yes       no       no      yes
7  Jack       no      yes       no       no      yes       no

Я бы хотел получить один столбец для состояния вместо нескольких столбцов. Конечный результат будет выглядеть так:

   name    Q1State   Q2State
1  John     State2    State2
2  Jane     State1    State1
3   Joe     State1    State1
4   Jim     State3    State3
5 Jeane     State3    State3
6  Jeff     State3    State3
7  Jack     State2    State2

Я могу использовать unite(DF, State1, State2, State3) для выполнения sh второй части моей задачи без затруднений. Моя проблема связана с промежуточным шагом. Я не знаю, как выполнить sh заполнение ячеек с соответствующим названием состояния или пробелом. Я хотел бы, чтобы это выглядело так:

   name Q1State1 Q1State2 Q1State3  Q2State1  Q2State2  Q2State3
1  John            State2                       State2          
2  Jane State1                        State1                        
3   Joe State1                        State1                    
4   Jim                     State3                        State3
5 Jeane                     State3                        State3
6  Jeff                     State3                        State3 
7  Jack            State2                       State2   

Аналогичный вопрос Заменить значения в столбце с указанием c значения строки из того же столбца, используя l oop, опубликованный ранее, но это один использовал первый ряд данных, чтобы заполнить ячейки. Я пытался использовать подобное кодирование в dplyr, но я не могу понять, как правильно назвать имена столбцов.

DF %>% 
  mutate_at(vars(starts_with('State')), ~ case_when(. == 'yes' ~colnames(.), TRUE ~ ''))

С этим кодом я получаю ошибку. Я не уверен, как определить, что заголовок столбца будет использоваться для заполнения ячеек. Я сказал, что пытался использовать mutate в dplyr, но не могу понять, как правильно вызывать заголовок столбца.

Ответы [ 4 ]

1 голос
/ 17 марта 2020

Возможны следующие варианты:

DF %>%
 transmute(Name,
           State = names(.)[max.col(. == "yes")])

   Name  State
1  John State2
2  Jane State1
3   Joe State1
4   Jim State3
5 Jeane State3
6  Jeff State3
7  Jack State2

Параметр для обновленного вопроса с добавлением tidyr:

DF %>%
 pivot_longer(-Name) %>%
 extract(name, into = c("name1", "name2"), "(Q*\\d+)([[:alnum:]]+)") %>%
 filter(value == "yes") %>%
 select(-value) %>%
 mutate(name1 = paste0(name1, "State")) %>%
 pivot_wider(names_from = "name1", values_from = "name2") 

  Name  Q1State Q2State
  <chr> <chr>   <chr>  
1 John  State2  State2 
2 Jane  State1  State1 
3 Joe   State1  State1 
4 Jim   State3  State3 
5 Jeane State3  State3 
6 Jeff  State3  State3 
7 Jack  State2  State2 
0 голосов
/ 18 марта 2020

Использование data.table

DF2 <- dcast(melt(DF, id.vars="Name")[value == "yes"][, c("Q", "State") := tstrsplit(variable, "State")][, -c("value", "variable")], ... ~ Q)

Предоставление

    Name Q1 Q2
1:  Jack  2  2
2:  Jane  1  1
3: Jeane  3  3
4:  Jeff  3  3
5:   Jim  3  3
6:   Joe  1  1
7:  John  2  2
0 голосов
/ 17 марта 2020

Опция с data.table

library(data.table)
melt(setDT(DF), id.var = 'Name', variable.name = 'State')[
         value == 'yes'][, value := NULL][]
#    Name  State
#1:  Jane State1
#2:   Joe State1
#3:  John State2
#4:  Jack State2
#5:   Jim State3
#6: Jeane State3
#7:  Jeff State3

data

Name <- c("John", "Jane", "Joe", "Jim", "Jeane", "Jeff", "Jack")
State1 <- c("no", "yes", "yes", "no", "no", "no", "no")
State2 <- c("yes", "no", "no", "no", "no", "no", "yes")
State3 <- c("no", "no", "no", "yes", "yes", "yes", "no")
DF <- data.frame(Name, State1, State2, State3)
0 голосов
/ 17 марта 2020

Вы можете преобразовать в длинный формат и фильтровать:

Name <- c("John", "Jane", "Joe", "Jim", "Jeane", "Jeff", "Jack")
State1 <- c("no", "yes", "yes", "no", "no", "no", "no")
State2 <- c("yes", "no", "no", "no", "no", "no", "yes")
State3 <- c("no", "no", "no", "yes", "yes", "yes", "no")
DF <- data.frame(Name, State1, State2, State3)

DF %>%
  pivot_longer(-Name, names_to = "State", values_to = "value") %>%
  filter(value == "yes") #%>%
  # select(-value)

# # A tibble: 7 x 3
# Name  State  value
# <fct> <chr>  <fct>
#   1 John  State2 yes  
# 2 Jane  State1 yes  
# 3 Joe   State1 yes  
# 4 Jim   State3 yes  
# 5 Jeane State3 yes  
# 6 Jeff  State3 yes  
# 7 Jack  State2 yes  
...