2017-01-06 2 views
1

Я пытаюсь использовать tidyr для разделения одного столбца в моем фрейме данных, применяя его только к определенным строкам. В то время как dplyr :: filter выполняет задание, он пропускает остальную часть моих данных. Есть ли чистый способ применения tidyr к определенным строкам, сохраняя при этом остальную часть данных нетронутой?Применение tidyr отдельно для определенных строк

вот пример моей проблемы:

#creating DF for the example 
df<-data.frame(var_a=letters[1:5], 
       var_b=c(sample(1:100,5)), 
       text=c("foo_bla","here_do","oh_yes","baa","land")) 

дает мне это:

var_a var_b text 
1  a 10 foo_bla 
2  b 58 here_do 
3  c 34 oh_yes 
4  d  1  baa 
5  e 47 land 
#separating one col: 
clean_df<-df %>% separate(text,into=c("first","sec"),sep="_",remove=F) 
clean_df 
var_a var_b text first sec 
1  a 10 foo_bla foo bla 
2  b 58 here_do here do 
3  c 34 oh_yes oh yes 
4  d  1  baa baa <NA> 
5  e 47 land land <NA> 

Я хочу разделить только «here_do " ряд , Заранее благодарим за помощь!

ответ

2

Другой подход:

cols_to_split = c('here_do') 

clean_df <-df %>% 
    filter(text %in% cols_to_split) %>% 
    tidyr::separate(text,into=c("first","sec"),sep="_",remove=F) %>% 
    bind_rows(filter(df, !text %in% cols_to_split)) 


# var_a var_b text first sec 
#1  b  7 here_do here do 
#2  a 26 foo_bla <NA> <NA> 
#3  c 23 oh_yes <NA> <NA> 
#4  d  2  baa <NA> <NA> 
#5  e 67 land <NA> <NA> 

Если вам нужно сохранить остальную часть строк в колонке «первый», вы можете использовать:

clean_df <-df %>% 
    filter(text %in% cols_to_split) %>% 
    tidyr::separate(text,into=c("first","sec"),sep="_",remove=F) %>% 
    bind_rows(filter(df, !text %in% cols_to_split)) %>% 
    mutate(first = ifelse(is.na(first), as.character(text), first)) 

# var_a var_b text first sec 
#1  b  7 here_do here do 
#2  a 26 foo_bla foo_bla <NA> 
#3  c 23 oh_yes oh_yes <NA> 
#4  d  2  baa  baa <NA> 
#5  e 67 land land <NA> 
+0

хорошая попытка, но OP хочет столбец 'first' иметь остальной части текста, как есть. Это то, что я понял из вопроса –

+0

@akrun no .. вы сталкиваетесь? –

+0

Спасибо за разные подходы! Я многому научился от чтения ваших ответов, я принимаю это, потому что мне не нужно указывать шаблон, который будет использоваться для разделения, а также он может быть обобщен на другие проблемы, с которыми я сталкиваюсь при использовании dplyr и tidyr. – Nooga

1

Мы можем сделать это в base R путем замены разделителя для «here_do» в столбце «текст», т.е. изменить его на «здесь делать», используя sub, читать его с read.csv и cbind с исходным набором данных

cbind(df, read.csv(text=sub("(?<=here)_(?=do)", ",", df$text, 
     perl = TRUE), header=FALSE, col.names = c("first", "sec"))) 
# var_a var_b text first sec 
#1  a 93 foo_bla foo_bla  
#2  b 51 here_do here do 
#3  c 65 oh_yes oh_yes  
#4  d 70  baa  baa  
#5  e 32 land land  

Или, если нам нужен tidyr решение, использовать extract

library(tidyr) 
extract(df, text, into = c("first", "sec"), "(here)_(do)", remove = FALSE) 
# var_a var_b text first sec 
#1  a 93 foo_bla <NA> <NA> 
#2  b 51 here_do here do 
#3  c 65 oh_yes <NA> <NA> 
#4  d 70  baa <NA> <NA> 
#5  e 32 land <NA> <NA> 
Смежные вопросы