【问题标题】:Check whether an element in a character vector can be converted to numeric in R检查字符向量中的元素是否可以转换为R中的数字
【发布时间】:2021-08-04 12:08:39
【问题描述】:

如何检查字符向量的元素是否可以转换为数字?更准确地说,当元素是浮点数或整数时,它可以毫无问题地转换为数字,但是当它是字符串时,会出现警告:“NAs introduced by coercion”。我能够通过 NA 值的索引间接检查。但是,如果能够在没有收到警告的情况下执行此操作会更简洁。

cat1 <- c("1.12354","1.4548","1.9856","some_string")
cat2 <- c("1.45678","1.1478","1.9565","1.32315")
target <- c(0,1,1,0)
df <- data.frame(cat1, cat2, target)
catCols <- c("cat1", "cat2")

for(col in catCols){
a <- as.numeric(unique(df[[col]]))
if(length(which(is.na(a))) != 0){
print(col)
print(which(is.na(a)))
 }
}

【问题讨论】:

  • 你的目标是什么?如果您有一些不可强制的数字,as.numeric 函数会向您发出警告。你只是想抑制警告?
  • 这能回答你的问题吗? Test for numeric elements in a character string
  • 您要么将整个向量转换为数字,要么将其保留为字符串。您想在这里实现什么目标?
  • @TimBiegeleisen 我想确定出现此警告的元素和列
  • @Laterow 这很有帮助,谢谢

标签: r vector null character


【解决方案1】:

也许,您可以使用正则表达式来查找列中的所有值是整数还是浮点数。

can_convert_to_numeric <- function(x) {
  all(grepl('^(?=.)([+-]?([0-9]*)(\\.([0-9]+))?)$', x, perl = TRUE))  
}

sapply(df[catCols], can_convert_to_numeric)
# cat1  cat2 
#FALSE  TRUE 

或者,要获取无法转换为数字的值,我们可以使用grep as:

values_which_cannot_be_numeric <- function(x) {
  grep('^(?=.)([+-]?([0-9]*)(\\.([0-9]+))?)$', x, perl = TRUE, invert = TRUE, value = TRUE)
}

lapply(df[catCols], values_which_cannot_be_numeric)

#$cat1
#[1] "some_string"

#$cat2
#character(0)

正则表达式取自here


如果您使用type.convert,您完全不必担心这一点。

df <- type.convert(df, as.is = TRUE)
str(df)

#'data.frame':  4 obs. of  3 variables:
# $ cat1  : chr  "1.12354" "1.4548" "1.9856" "some_string"
# $ cat2  : num  1.46 1.15 1.96 1.32
# $ target: int  0 1 1 0

【讨论】:

  • 带指数的数字文字呢?十六进制呢?
  • @RonakSkah 我也想找到不能转换成数字的值
  • @moli 要获取无法转换为数字的值,请参阅更新后的答案。
【解决方案2】:

一种解决方案是编写一个函数,返回要应用于所需列的NA 值的索引。

check_num <- function(x){
  y <- suppressWarnings(as.numeric(x))
  if(any(is.na(y))){
    which(is.na(y))
  } else invisible(NULL)
}
lapply(df[catCols], check_num)
#$cat1
#[1] 4
#
#$cat2
#NULL

如果所有值都可以转换为数字,则上述函数返回NULL。下一个函数遵循相同的方法来确定可以转换哪些向量元素,但如果所有都可以转换,则返回 integer(0)

check_num2 <- function(x){
  y <- suppressWarnings(as.numeric(x))
  which(is.na(y))
}
lapply(df[catCols], check_num2)
#$cat1
#[1] 4
#
#$cat2
#integer(0)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-27
    • 2022-10-15
    • 2017-12-26
    • 2017-10-27
    • 2016-10-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多