Подтвердить что ты не робот

Тест для числовых элементов в символьной строке

Я хочу проверить строку символов и посмотреть, какие элементы могут быть действительно числовыми. Я могу использовать регулярное выражение для проверки успешного целого числа, но я хочу посмотреть, какие элементы имеют все цифры и 1 или менее десятичные числа. Ниже я попытался:

x <- c("0.33", ".1", "3", "123", "2.3.3", "1.2r")
!grepl("[^0-9]", x)   #integer test

grepl("[^0-9[\\.{0,1}]]", x)  # I know it wrong but don't know what to do

Я ищу логический вывод, поэтому ожидаю следующих результатов:

[1] TRUE TRUE TRUE TRUE FALSE FALSE
4b9b3361

Ответ 1

Возможно, есть причина, по которой некоторые другие части ваших данных более сложны, и это может сломать это, но моя первая мысль:

> !is.na(as.numeric(x))
[1]  TRUE  TRUE  TRUE  TRUE FALSE FALSE

Как указано ниже Джошем О'Брайеном, это не будет воспринимать такие вещи, как 7L, которые интерпретирует интерпретатор R как целое число 7. Если вам нужно включить их как "правдоподобно числовые", один маршрут будет сначала выберите их с помощью регулярного выражения,

x <- c("1.2","1e4","1.2.3","5L")
> x
[1] "1.2"   "1e4"   "1.2.3" "5L"   
> grepl("^[[:digit:]]+L",x)
[1] FALSE FALSE FALSE  TRUE

... и затем разделите "L" только на те элементы, используя gsub и индексирование.

Ответ 2

Недавно я столкнулся с аналогичной проблемой, когда я пытался написать функцию для форматирования значений, передаваемых в виде символьной строки из другой функции. Отформатированные значения в конечном итоге окажутся в таблице, и я хотел бы создать логику для идентификации NA, символьных строк и символьных представлений чисел, чтобы я мог применить к ним sprintf() перед созданием таблицы.

Хотя более сложно читать, мне нравится надежность подхода grepl(). Я думаю, что это приводит все примеры, приведенные в комментариях.

x <- c("0",37,"42","-5","-2.3","1.36e4","4L","La","ti","da",NA)

y <- grepl("[-]?[0-9]+[.]?[0-9]*|[-]?[0-9]+[L]?|[-]?[0-9]+[.]?[0-9]*[eE][0-9]+",x)

Это будет оценено (отформатировано для помощи при визуализации):

x
[1] "0"  "37"   "42"  "-5"   "-2.3"   "1.36e4" "4L" "La"     "ti"     "da"     NA 

y
[1] TRUE  TRUE   TRUE  TRUE   TRUE     TRUE    TRUE FALSE   FALSE    FALSE    FALSE

Регулярное выражение TRUE для:

  • положительные или отрицательные числа не более чем с одним десятичным символом ИЛИ
  • положительные или отрицательные целые числа (например, 4L) OR
  • положительные или отрицательные числа в научной нотации

Дополнительные термины могут быть добавлены для обработки десятичных знаков без предшествующей цифры или цифр с десятичной точкой, но не цифр после десятичной, если набор данных содержит числа в плохом виде.

Ответ 3

Вдохновленные ответами здесь, моя функция обрезает начальные и конечные пробелы, может обрабатывать na.strings и, необязательно, обрабатывать NA как числовые значения. Регулярное выражение также улучшилось. См. Справочную информацию для деталей. Все, что ты хочешь!

check if a str obj is actually numeric
@description check if a str obj is actually numeric
#' @param x a str vector, or a factor of str vector, or numeric vector. x will be coerced and trimws.
#' @param na.strings case sensitive strings that will be treated to NA.
#' @param naAsTrue whether NA (including actual NA and na.strings) will be treated as numeric like
#' @return a logical vector (vectorized).
#' @export
#' @note Using regular expression
#' \cr TRUE for any actual numeric c(3,4,5,9.9) or c("-3","+4.4",   "-42","4L","9L",   "1.36e4","1.36E4",    NA, "NA", "","NaN", NaN): 
#' \cr positive or negative numbers with no more than one decimal c("-3","+4.4") OR
#' \cr positive or negative integers (e.g., c("-42","4L","39L")) OR
#' \cr positive or negative numbers in scientific notation c("1.36e4","1.36E4")
#' \cr NA, or na.strings
is.numeric.like <- function(x,naAsTrue=TRUE,na.strings=c('','.','NA','na','N/A','n/a','NaN','nan')){
    x = trimws(x,'both')
    x[x %in% na.strings] = NA
    # https://stackoverflow.com/a/21154566/2292993
    result = grepl("^[\\-\\+]?[0-9]+[\\.]?[0-9]*$|^[\\-\\+]?[0-9]+[L]?$|^[\\-\\+]?[0-9]+[\\.]?[0-9]*[eE][0-9]+$",x,perl=TRUE)
    if (naAsTrue) result = result | is.na(x)
    return((result))
}

Ответ 4

Вы также можете использовать:

readr::parse_number("I am 4526dfkljvdljkvvkv")

Чтобы получить 4526.