【问题标题】:class of variable is list in data.table变量类是 data.table 中的列表
【发布时间】:2021-02-23 10:21:56
【问题描述】:

假设我有以下数据:

library(data.table)
library(tidyverse)
Data <- 
  data.table(A = c("foo 32.3 56.2421 4.5 3.66", 
                 "365.11 9812.3 foooo 5.66 8.31",
                 ""))

有些行有四个数字,有些则没有。 我想要两个带有这些数字的新列。这是我的代码:

Data[, str_c("Number", 1:4) := str_extract_all(A, "\\d+\\.\\d") %>% transpose]

它工作得很好,但在第三行中,我在变量 Number1Number2 中得到了 NULL(我想要 NA)。

真正的问题是Number1Number4 的类是list,但我想要character(在下一步中甚至更好numeric)。

我怎样才能做到这一点?我想使用带有提取和data.table 的代码。

【问题讨论】:

    标签: r list data.table extract


    【解决方案1】:

    您可以使用lapply 将值转换为数字,如果值不存在则返回NA,然后转置结果以创建两个新列。

    library(data.table)
    
    Data[, c("Number1", "Number2") := lapply(stringr::str_extract_all(A, "\\d+"), 
           function(x) if(length(x)) as.numeric(x) else NA) %>% transpose()]
    
    Data
    
    #                A Number1 Number2
    #1:      foo 32 56      32      56
    #2: 365 9812 foooo     365    9812
    #3:                     NA      NA
    

    使用tidyrextract 你可以这样做:

    tidyr::extract(Data, A, c("Number1", "Number2"), 
                  '(\\d+).*(\\d+)', remove = FALSE, convert = TRUE)
    
    #                A Number1 Number2
    #1:      foo 32 56      32       6
    #2: 365 9812 foooo     365       2
    #3:                     NA      NA
    

    【讨论】:

    • 谢谢!不幸的是,我正在寻找一种我的客户很容易理解的简单解决方案。
    • @TobiSonne 你是什么意思?
    • 我认为function(x) if(length(x)) as.numeric(x) else NA) 部分相当复杂(不是为了我,而是为了解释)。我特别不想解释为什么会有NULL 值。我正在寻找类似tidyrseparate 的东西,其中缺失的值会自动填充NA(但由于我的真实数据的结构,我不想在这里单独使用)。
    • 你可以使用tidyrextract函数。
    • 谢谢!不知道那个功能。不幸的是,对于我的真实情况,这也不起作用。我有四个数字,它们带有小数,我不想使用正则表达式"(\\d+\\.\\d+).*(\\d+\\.\\d+).*(\\d+\\.\\d+).*(\\d+\\.\\d+)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-16
    • 2020-08-25
    • 2015-07-15
    • 2015-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多