извлечь регулярное выражение из столбца и заменить - PullRequest
0 голосов
/ 06 марта 2020

Я надеюсь прочитать файл и обработать его в R. Он имеет следующий формат:

tibble(row=8,name="Shawn",state="Arizona", age=45,
comments="father=Alex;NSM;GNO;One:0.9995,0.13|Two:0.9991,0.55|Three:0.9996,0.33|Four:0.9986,0.22|Five:0.9987,0.22")
# A tibble: 1 x 5
        row name  state     age comment                                                                          
      <dbl> <chr> <chr>   <dbl> <chr>                                                                             
    1     8 Shawn Arizona    45 father=Alex;NSM;GNO;One:0.9995,0.13|Two:0.9991,0.55|Three:0.9996,0.33|Four:0.9986…

Я хотел бы заменить последний столбец на

comment
One:0.9995|Two:0.9991|Three:0.9996|Four:0.9986|Five:0.9987

и затем вычтите плавающее число из 1:

comment
One:0.0005|Two:0.0009|Three:0.0004|Four:0.0014|Five:0.0013

Ответы [ 3 ]

2 голосов
/ 06 марта 2020

Эта функция не особенно производительна или элегантна, но она даст вам именно тот результат, который вы запрашивали. Он не векторизован, но вы можете использовать sapply, чтобы исправить это.

sample <- "father=Alex;NSM;GNO;One:0.9995,0.13|Two:0.9991,0.55|Three:0.9996,0.33|Four:0.9986,0.22|Five:0.9987,0.22"

extract_numbers <- function(x) {
  x <- sub(".*;", "", x)
  x <- gsub(",([0-9.]*)|", "", x)
  x <- strsplit(x, "|", fixed = TRUE)[[1]]
  do.call(
    "paste", 
    c(
      lapply(
        strsplit(x, ":"), 
        function(y) paste(y[1], sprintf("%6.4f", 1 - as.numeric(y[2])), sep = ":")
      ),
      sep = "|"
    )
  )
}

extract_numbers(sample)
# [1] "One:0.0005|Two:0.0009|Three:0.0004|Four:0.0014|Five:0.0013"
1 голос
/ 06 марта 2020

Мы можем решить это, используя tidyverse. Сначала мы удаляем символы до последней точки с запятой и цифры, за которыми следует запятая, используя gsub. Мы разбиваем строки на "|" на отдельные строки и делим их на ":" в разных столбцах, а затем вычитаем значение из 1.

library(dplyr)
library(tidyr)

df %>%
  mutate(comments = gsub(".*;|,\\d\\.\\d+", "", comments)) %>%
  separate_rows(comments, sep = "\\|") %>%
  separate(comments, into = c('num', 'value'), sep = ":", convert = TRUE) %>%
  mutate(value = 1 - value)

# A tibble: 5 x 6
#    row name  state     age num      value
#  <dbl> <chr> <chr>   <dbl> <chr>    <dbl>
#1     8 Shawn Arizona    45 One   0.000500
#2     8 Shawn Arizona    45 Two   0.0009  
#3     8 Shawn Arizona    45 Three 0.000400
#4     8 Shawn Arizona    45 Four  0.00140 
#5     8 Shawn Arizona    45 Five  0.00130 

При необходимости, как суммарное значение, мы можем добавить к цепочке

%>% group_by(row, name, state, age) %>%
    summarise(comments = paste(num, round(value, 5), collapse = "|", sep = ":"))

#   row name  state     age comments                                                  
#  <dbl> <chr> <chr>   <dbl> <chr>                                                     
#1     8 Shawn Arizona    45 One:0.0005|Two:0.0009|Three:0.0004|Four:0.0014|Five:0.0013
1 голос
/ 06 марта 2020

Вы можете использовать strsplit и tstrsplit из data.table следующим образом (назовите ваш стол DT):

library(data.table)
setDT(DT)

DT = DT[ , c(.SD, tstrsplit(comments, ';', fixed = TRUE))]
DT = DT[ , strsplit(V9, '|', fixed = TRUE), by = row]
DT[ , c('key', 'val1', 'val2') := tstrsplit(V1, '[:,]', type.convert = TRUE)]
DT[ , val1 := 1-val1][]
#      row                V1    key   val1  val2
# 1:     8   One:0.9995,0.13    One 0.0005  0.13
# 2:     8   Two:0.9991,0.55    Two 0.0009  0.55
# 3:     8 Three:0.9996,0.33  Three 0.0004  0.33
# 4:     8  Four:0.9986,0.22   Four 0.0014  0.22
# 5:     8  Five:0.9987,0.22   Five 0.0013  0.22

tstrsplit делает strsplit, а затем transpose - - это берет входную строку x и превращает ее в один столбец для каждого результата split каждого элемента x.

На втором шаге я предположил, что row является уникальным идентификатор каждой строки. Это может быть медленным, если есть много row с - вы можете попробовать здесь для некоторых других подходов к "unnesting" V9 в разные строки.

Тогда мы tstrsplit снова, чтобы получить желаемое значение в качестве собственного столбца; обратите внимание, что type.convert автоматически преобразует столбцы, которые выглядят как числа, в числа (вместо цифр в виде строк).

Мы можем изменить это, если вы хотите вернуть данные в исходный формат строки, но это Будет проще работать с вашими данными в текущем формате.

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