dplyr mutate + unlist проблема - PullRequest
       1

dplyr mutate + unlist проблема

0 голосов
/ 12 декабря 2018

Я пытаюсь извлечь часть символа во фрейме данных.

d<-data.frame(a=c("aa_bb_cc", "ddd_eee_fff", "sss_rrr_eee"))

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

unlist(str_split(d$a[1],"_"))[2]
unlist(str_split(d$a[2],"_"))[2]

Поэтому я применяю ее в mutate (dplyr):

t<-d %>% mutate(new1=(unlist(str_split(a,"_"))[2])) 

Но результат во всех случаях "bb".Что я делаю не так?

Ответы [ 4 ]

0 голосов
/ 12 декабря 2018

Мы можем использовать str_extract

library(tidyverse)
d %>% 
   mutate(new = str_extract(a, "(?<=_)[^_]+"))
#            a new
#1    aa_bb_cc  bb
#2 ddd_eee_fff eee
#3 sss_rrr_eee rrr

Или с base R

d$new <- read.table(text = as.character(d$a), header = FALSE, sep="_")[,2]
0 голосов
/ 12 декабря 2018
d1 <- as.data.frame(unlist(str_split_fixed(d$a,"_", n =3)))

Надеюсь, что это работает

0 голосов
/ 12 декабря 2018

Может быть, хорошее оправдание, чтобы начать использовать (настраиваемые) регулярные выражения:

d[["new"]] <- gsub(".*_(.*)_.*", "\\1", d[["a"]])
d
            a new
1    aa_bb_cc  bb
2 ddd_eee_fff eee
3 sss_rrr_eee rrr
0 голосов
/ 12 декабря 2018

Когда вы делаете

d %>% mutate(new1=(unlist(str_split(a,"_"))[2]))

, он передает a столбец в str_split.Так что это эквивалентно

unlist(str_split(d$a, "_"))
#[1] "aa"  "bb"  "cc"  "ddd" "eee" "fff" "sss" "rrr" "eee"

, и теперь, когда вы его поднабориваете и получаете 2-й элемент, оно дает

unlist(str_split(d$a, "_"))[2]
#[1] "bb"

Следовательно, это значение присваивается всем случаям.


Чтобы решить эту проблему, вы можете добавить операцию rowwise, чтобы получить желаемый результат, так как она будет передавать значение a для каждой строки отдельно в str_split.

library(tidyverse)

d %>%
  rowwise() %>%
  mutate(new1= unlist(str_split(a,"_"))[2])

#      a      new1 
#    <fct>    <chr>
#1 aa_bb_cc    bb   
#2 ddd_eee_fff eee  
#3 sss_rrr_eee rrr  

Или другой более безопасный вариант - использовать separate и разделить строку на разные столбцы на основе разделителя и select соответствующий столбец

d %>%
  separate(a, into = c("one", "two", "three"), sep = "_", remove = FALSE) %>%
  select(a, two)

#            a two
#1    aa_bb_cc  bb
#2 ddd_eee_fff eee
#3 sss_rrr_eee rrr

Очевидно, что вы также можете использовать опцию base Rиспользуя sapply и strsplit

sapply(strsplit(as.character(d$a), "_"), "[[", 2)
#[1] "bb"  "eee" "rrr"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...