Regex соответствует последнему вхождению символа в строку

Я хотел бы сопоставить последнее вхождение «,» в строке, чтобы иметь возможность правильно separate столбца.

Образец данных

tibble(
  name = c("John", "James"), 
  company_num = c("Apple, Inc, 1000",
                  "Microsoft, 1200")
)

Желаемый результат:

# A tibble: 2 x 3
  name  company      num
  <chr> <chr>      <dbl>
1 John  Apple, Inc  1000
2 James Microsoft   1200

Что я пробовал

df %>% 
  separate(col = company_num, 
           into = c("company", "num"), 
           sep = ", ")
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
86
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Я уверен, что здесь есть однострочное решение tidyverse, но вот базовый метод R:

# Get location of last comma
widths  <- regexpr(",[^,]*$", df$company_num)

# Treat company_num as fixed width format file
df[c("Company", "Number")]  <- read.fwf(
    textConnection(df$company_num), 
    widths,
    col.names = c("Company", "Number")
)

# Remove trailing comma/space
df$Company  <- sub(",\\s?$", "", df$Company)

df

# A tibble: 2 x 4
#   name  company_num      Company    Number
#   <chr> <chr>            <chr>       <int>
# 1 John  Apple, Inc, 1000 Apple, Inc   1000
# 2 James Microsoft, 1200  Microsoft    1200

Обновление - решение tidyverse

Если это должно быть tidyverse, то, в значительной степени заимствуя ответ на этот вопрос, вы можете сделать:

df |>
    separate(
        col = company_num, 
        into = c("company", "num"), 
        sep = "(?=[[:digit:]])", extra = "merge"
    ) |>
    mutate(
        company = sub(",\\s?$", "", company),
        num = as.numeric(num)
    )

# # A tibble: 2 x 3
#   name  company      num
#   <chr> <chr>      <dbl>
# 1 John  Apple, Inc  1000
# 2 James Microsoft   1200

Большое спасибо! К сожалению, для спокойствия команд - мне очень нужно решение tidyverse/tidyr с separate

Tom 12.10.2022 10:18

С пакетом stringr и регулярным выражением, в частности с положительным просмотром вперед или назад, с (?=lookahead) и (?<=lookbehind).

Предполагая, что ваш фрейм данных или табличка df:

df %>% mutate(

company = stringr::str_extract(company_num, ".*(?=,.*$)"),
#  ↑ capture the text BEFORE a comma that is followed by one or several character ".*" at the end of the string "$"

num = stringr::str_extract(company_num, "(?<=, )[0-9]*$")) %>%
# ↑ capture one or several digits at the end of the string ($), preceded by ',' 

select(-company_num)
# ↑ drop the "company_num" col

Вы можете поставить лайк sub.

data.frame(x[1],
           company = sub(",[^,]*$", "", x$company_num),
           num = sub(".*, ", "", x$company_num))
#   name    company  num
#1  John Apple, Inc 1000
#2 James  Microsoft 1200

Данные

x <- data.frame(name = c("John", "James"), 
                company_num = c("Apple, Inc, 1000", "Microsoft, 1200") )

С правильным регулярным выражением вы можете использовать separate в одной строке.

Это помещает запятую в группу захвата (, ), где за этой запятой не может стоять другая запятая (?!.*,).

library(tidyr)
library(dplyr)

df %>% separate(company_num, into = c("company", "num"), sep = "(, )(?!.*,)")

# A tibble: 2 × 3
  name  company    num  
  <chr> <chr>      <chr>
1 John  Apple, Inc 1000 
2 James Microsoft  1200 

Другие вопросы по теме