Оставить соединение с несколькими условиями в R - PullRequest
0 голосов
/ 21 января 2019

Я пытаюсь заменить идентификаторы для их соответствующих значений. Проблема в том, что каждый идентификатор имеет свое значение в соответствии с предыдущим столбцом type, например:

>df
  type id 
1  q1   1
2  q1   2
3  q2   1
4  q2   3
5  q3   1
6  q3   2

Вот идентификаторы типов со значением:

>q1
  id value
1 1  yes
2 2  no

>q2 
   id value
1  1  one hour
2  2  two hours
3  3  more than two hours

>q3
  id value
1 1  blue
2 2  yellow

Я пробовал что-то вроде этого:

df <- left_join(subset(df, type %in% c("q1"), q1, by = "id"))

Но он удаляет другие значения.

Я хотел бы знать, как сделать one liner solution (или что-то вроде), потому что существует более 20 векторов с описанием типов.

Есть идеи, как это сделать?

Это то, что я ожидаю:

>df
  type id value
1  q1   1 yes
2  q1   2 no
3  q2   1 one hour
4  q2   3 more than two hours
5  q3   1 blue
6  q3   2 yellow

Ответы [ 4 ]

0 голосов
/ 21 января 2019

Вы можете сделать это серией левых соединений:

df1 = left_join(df, q1, by='id') %>% filter(type=="q1")
> df1
  type id value
1   q1  1   yes
2   q1  2    no


df2 = left_join(df, q2, by='id') %>% filter(type=="q2")
> df2
  type id               value
1   q2  1            one hour
2   q2  3 more than two hours

df3 = left_join(df, q3, by='id') %>% filter(type=="q3")
> df3
  type id  value
1   q3  1   blue
2   q3  2 yellow

> rbind(df1,df2,df3)
  type id               value
1   q1  1                 yes
2   q1  2                  no
3   q2  1            one hour
4   q2  3 more than two hours
5   q3  1                blue
6   q3  2              yellow

Один лайнер будет:

rbind(left_join(df, q1, by='id') %>% filter(type=="q1"),
        left_join(df, q2, by='id') %>% filter(type=="q2"),
            left_join(df, q3, by='id') %>% filter(type=="q3")) 

Если у вас больше векторов, то, вероятно, вам следует перебрать имена векторных типов и выполнить по очереди left_join и bind_rows:

vecQs = c(paste("q", seq(1,3,1),sep="")) #Types of variables q1, q2 ...
result = tibble()

#Execute left_join for the types and store it in result.
for(i in vecQs) {       
     result = bind_rows(result, left_join(df,eval(as.symbol(i)) , by='id') %>% filter(type==!!i))
}

Это даст:

> result
# A tibble: 6 x 3
  type     id value              
  <chr> <int> <chr>              
1 q1        1 yes                
2 q1        2 no                 
3 q2        1 one hour           
4 q2        3 more than two hours
5 q3        1 blue               
6 q3        2 yellow
0 голосов
/ 21 января 2019
tempList = split(df, df$type)
do.call(rbind,
          lapply(names(tempList), function(nm)
              merge(tempList[[nm]], get(nm))))
#  id type               value
#1  1   q1                 yes
#2  2   q1                  no
#3  1   q2            one hour
#4  3   q2 more than two hours
#5  1   q3                blue
#6  2   q3              yellow
0 голосов
/ 21 января 2019

Получите значения идентификаторов объектов data.frame 'q \ d +' в list, свяжите их вместе в один data.frame с bind_rows, создавая столбец 'type' в качестве имени идентификатора и * 1003.* с объектом набора данных 'df'

library(tidyverse)
mget(paste0("q", 1:3)) %>% 
    bind_rows(.id = 'type') %>% 
    right_join(df)
#  type id               value
#1   q1  1                 yes
#2   q1  2                  no
#3   q2  1            one hour
#4   q2  3 more than two hours
#5   q3  1                blue
#6   q3  2              yellow
0 голосов
/ 21 января 2019

Вы можете присоединиться к нескольким переменным. Пример, который вы дадите, на самом деле создаст для этого подходящую таблицу поиска:

value_lookup <- data.frame(
  type = c('q1', 'q1', 'q2', 'q2', 'q3', 'q3'),
  id = c(1, 2, 1, 3, 1, 2),
  value = c('yes', 'no', 'one hour', 'more than two hours', 'blue', 'yellow')
)

Тогда вы просто сливаетесь на type и id:

df <- left_join(df, value_lookup, by = c('type', 'id'))  

Обычно, когда мне нужна такая таблица поиска, я сохраняю ее в формате CSV, а не записываю все это в коде, но делаю все, что вам подходит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...