【问题标题】:Is it possible to treat numbers with multiple decimal points as numeric to check for letter characters present in column and sort column in R?是否可以将具有多个小数点的数字视为数字来检查 R 中列和排序列中存在的字母字符?
【发布时间】:2021-10-16 22:09:21
【问题描述】:

我有一个数据框,其中一列的数字混合了整数、数字和多个小数点(例如,3、1.1、1.2.1、1.2.2.3)。我有两个问题:

  1. 如何检查以确保列中仅使用数字(即不存在字符)?如果存在字符,那么是哪几行?
  2. R 中有没有办法将这些视为数字以便对列进行排序?

最小示例

数据

library(dplyr)

df <-
  structure(list(
    index = 1:15,
    section = c("2.1.1", "2.1.1", "2.1.2.4", "2.1.3", "2.1.2.9", "2.1.4", 
                "2.1.4", "2.1.4", "3", "3", "4", "1.1", "1.5", "1.5", "b.1")),
  class = "data.frame",
  row.names = c(NA,-15L))

我的尝试

如果我尝试将列设为数字,那么它将带多个小数点的数字强制为NA

> as.numeric(df$section)
 [1]  NA  NA  NA  NA  NA  NA  NA  NA 3.0 3.0 4.0 1.1 1.5 1.5

警告信息:强制引入的 NAs

然后,为了测试列中的字符,我知道如果我只有整数或常规数值,我可以这样做来测试哪些行有字符(不包括 NA):

# Check for which (if any) rows have NAs.
na.index <- which(is.na(df$section))

# Find any rows that are character, excluding NAs (hence the setdiff).
index <- which(is.na(as.numeric(as.character(df$section)))) %>%
  setdiff(na.index)

# Output
index

[1]  1  2  3  4  5  6  7  8 15

在这里,它将任何带有多个小数的数字视为字符(以及带有字母的数字)。因此,我希望能够将多个十进制数字视为数字,然后将 b.1 标记为字符。我可以创建一个新列来区分这些。

对于排序,base sort 似乎会正确排列它们,但不确定这是否一直有效。

sort(df$section)

#Output
[1] "1.1"     "1.5"     "1.5"     "2.1.1"   "2.1.1"   "2.1.2.4" "2.1.2.9" "2.1.3"   
"2.1.4"   "2.1.4"   "2.1.4"   "3"       "3"       "4"       "b.1" 

这是我的预期输出(考虑到排序和检查字母字符)。排序时,如果节号相同,则可以按索引列排序(值小者先排序)。

预期输出

   index section      type
1     12     1.1   numeric
2     13     1.5   numeric
3     14     1.5   numeric
4      1   2.1.1   numeric
5      2   2.1.1   numeric
6      3 2.1.2.4   numeric
7      5 2.1.2.9   numeric
8      4   2.1.3   numeric
9      6   2.1.4   numeric
10     7   2.1.4   numeric
11     8   2.1.4   numeric
12     9       3   numeric
13    10       3   numeric
14    11       4   numeric
15    15     b.1 character

我在 Java (here) 等其他语言中看到了一些关于 SO 的讨论,但不确定如何在 R 中处理它,特别是因为每行中的小数位数不同。

【问题讨论】:

    标签: r dataframe sorting numeric


    【解决方案1】:

    我们可以使用str_detect 来检查仅数字元素,并使用arrange 基于使用mixedsort 对“部分”进行排序

    library(dplyr)
    library(stringr)
    df %>% 
        mutate(type = c("character", "numeric")[1 +
            str_detect(section, "^[0-9.]+$")])%>%
        arrange(match(section, gtools::mixedsort(section)))
    

    -输出

    index section      type
    1     12     1.1   numeric
    2     13     1.5   numeric
    3     14     1.5   numeric
    4      1   2.1.1   numeric
    5      2   2.1.1   numeric
    6      3 2.1.2.4   numeric
    7      5 2.1.2.9   numeric
    8      4   2.1.3   numeric
    9      6   2.1.4   numeric
    10     7   2.1.4   numeric
    11     8   2.1.4   numeric
    12     9       3   numeric
    13    10       3   numeric
    14    11       4   numeric
    15    15     b.1 character
    

    【讨论】:

      【解决方案2】:

      我们可以使用str_detect 来检查字符串中是否有任何字母。要对列进行排序,请使用arrange:

      library(dplyr)
      library(stringr)
      df %>% 
          mutate(test = str_detect(section, "[a-zA-Z]")) %>% 
          arrange(section)
      

      输出:

        index section  test
      1     12     1.1 FALSE
      2     13     1.5 FALSE
      3     14     1.5 FALSE
      4      1   2.1.1 FALSE
      5      2   2.1.1 FALSE
      6      3 2.1.2.4 FALSE
      7      5 2.1.2.9 FALSE
      8      4   2.1.3 FALSE
      9      6   2.1.4 FALSE
      10     7   2.1.4 FALSE
      11     8   2.1.4 FALSE
      12     9       3 FALSE
      13    10       3 FALSE
      14    11       4 FALSE
      15    15     b.1  TRUE
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-13
        • 2020-05-22
        • 2012-11-19
        • 2015-12-22
        相关资源
        最近更新 更多