как отделить первые слова перед первым номером в списке в R - PullRequest
0 голосов
/ 11 сентября 2018

Мой список:

   A      B
1 Alex    but            
2 likes   lala 54 hi     
3 a lot   number and 33 hello
4 of      face soap 34 hello  
5 food    35 hello      

Я хотел бы извлечь строку слов перед первым числом в столбце B и превратить ее в новый столбец, столбец C. Мой желаемый вывод:

   A        B                        C 
1 Alex      but                   
2 likes     lala 54 hi               lala
3 a lot     number and 33 hello      number and
4 of        face soap 34 hello       face soap
5 food      35 hello             

Ответы [ 5 ]

0 голосов
/ 11 сентября 2018

Другой метод, использующий extract из tidyr:

library(dplyr)
library(tidyr)

df %>%
  extract(B, "C", "^([a-z\\s]+)\\d", remove = FALSE) %>%
  mutate(C = replace(C, is.na(C), ""))

Выход:

      A                   B           C
1  Alex                 but            
2 likes          lala 54 hi       lala 
3 a lot number and 33 hello number and 
4    of  face soap 34 hello  face soap 
5  food            35 hello            
0 голосов
/ 11 сентября 2018

Другой вариант, в базе R.

df <- data.frame(A=c("Alex", "likes", "a lot", "of", "food"), B=c("but", "lala 54 hi", "number and 33 hello", "face soap 34 hello", "35 hello"))
regmatches(df$B, gregexpr("^\\D*(?=\\d)", df$B, perl=TRUE))
# [[1]]
# character(0)
# [[2]]
# [1] "lala "
# [[3]]
# [1] "number and "
# [[4]]
# [1] "face soap "
# [[5]]
# [1] ""

Если вы не знакомы с регулярными выражениями:

  • ^: начало строки
  • \\D* ноль или более нецифров, аналогично [^0-9]*
  • (?=\\d) означает «ожидайте цифру вперед, но не включайте ее в возвращаемый шаблон» (хороший пример для поиска: https://www.regular -expressions.info / lookaround.html );это расширение perl для регулярного выражения, то есть perl=TRUE

. Это дает вектор длины 0 для первого.С этим достаточно легко справиться, возможно, с помощью функции быстрого помощника:

replace_len0 <- function(x, replace=NA) `[<-`(x, lengths(x) < 1, replace)
unlist(replace_len0(regmatches(df$B, gregexpr("^\\D*(?=\\d)", df$B, perl=TRUE)), ""))
# [1] ""            "lala "       "number and " "face soap "  ""           

(я установил замену по умолчанию на NA, потому что, на мой взгляд, разница между "естьпустая строка "" перед первым числом " и " нет номера ". Вам.)

Это можно легко присвоить df$C при необходимости.

0 голосов
/ 11 сентября 2018

Используя положительный упреждающий просмотр, мы можем найти текст, за которым следуют пробел и цифра, а затем вернуть этот текст, используя stringr::str_extract

library(stringr)
libary(dplyr)
df %>% mutate(C= str_extract(B,'\\D+(?= \\d+)'))


     A                   B          C
1  Alex                 but       <NA>
2 likes          lala 54 hi       lala
3 a lot number and 33 hello number and
4    of  face soap 34 hello  face soap
5  food            35 hello       <NA>

Более подробную информацию о стрингере и положительном упреждающем просмотре вы можете получить.отметьте здесь

0 голосов
/ 11 сентября 2018

Лучший способ решить эту проблему - использовать функции dplyr и stringr, которые поставляются с пакетом tidyverse.Вот код для решения вашей проблемы:

# install.packages('tidyverse')
library(tidyverse)

d <- tibble(A = c('Alex', 'likes', 'a lot', 'of', 'food'),
             B = c('but', 'lala 54 hi', 'number and 33 hello', 'face soap 34 hello', '35 hello'))

d %>% 
  mutate(C = str_extract(B, '\\D*(?=\\d)'))

Вот что вам нужно знать о том, как это работает:

dplyr::mutate создает новый столбец C. Данные, которые онточки в этом столбце создаются с помощью EXTRACTING (с использованием stringr::str_extract) символов из столбца B. Извлекаемые им данные извлекаются с использованием регулярного выражения.

Используемое здесь регулярное выражение \\D*(?=\\d).Это сложно и грубо выглядит, но то, что он делает, говорит: «Ищите любые нечисловые символы любой длины, которые предшествуют числу. Дайте мне эти символы, но не цифры».

Надеюсь, это поможет!

0 голосов
/ 11 сентября 2018

Надеюсь, это поможет.Используя sapply, вы применяете функцию gsub векторизованным образом через значения в столбце B и выводите отфильтрованный вектор.

new_column = sapply(df$B, function(x){gsub("^(.*?)[0-9].*", "\\1", x)})

Это даст вам вектор с отфильтрованными значениями в столбце B.Затем вы просто добавляете этот новый вектор в качестве нового столбца в свой фрейм данных:

df$C= new_column
...