【问题标题】:Extract first two digits for each number in the list in R data table为 R 数据表中列表中的每个数字提取前两位数字
【发布时间】:2020-08-20 04:40:34
【问题描述】:

我在数据表中有一个包含购买代码的列。如果在我的合同(每份合同 = 新行)中有一次购买,那么代码号只是一个字符类型变量(例如,11.25.64)。但是,如果我的合同有多次购买,那么代码将存储在一个列表中。它看起来像这样

dt n  codes
   1  11.25.64
   2  c('11.25.16', '25.84.78', '78.26.99')
   3  81.62.16
   4  c('16.25.16', '99.84.78', '28.26.99') 

为了分类,我只想提取每个代码的前两位数字。所以,我想创建一个新列并得到这样的结果:

 dt n  classification_codes
    1  11
    2  c('11', '25', '78')
    3  81
    4  c('16', '99', '28') 

我尝试执行以下代码

dt$classification_codes<- substr(dt$codes, start = 1, stop = 2)

然而,它只适用于我有一个代码的行,但对于带有列表变量的行,它给出'c('

dt n  classification_codes
    1  11
    2  c(
    3  81
    4  c(

然后我尝试使用不同的方法并做这样的事情

dt$classification_codes <- lapply(str_split(dt$codes, " "), substr, 1, 3)

但我得到以下输出。这似乎更接近我想要的,但仍然不是。当我执行代码时,好像列表中的第一个变量不可读

 dt n  classification_codes
    1  11
    2  c("c(", "\"25","\"78")
    3  81
    4  c("c(", "\"99", "\"28")

【问题讨论】:

  • “一次购买”和“多次购买”ID 有什么区别?是不是一个购买ID总是以11开头?如果您包含一个样本数据集并显示预期的输出应该是什么,这将非常有帮助。请参阅minimal reproducible example 以获得有用的指导。
  • 感谢您的指出!我提供了一些示例输入数据和一些预期输出
  • 您介意提供dput() 的示例数据(或者甚至只是您在上面复制的前四行)吗?

标签: r list datatable strsplit


【解决方案1】:

这是您可以尝试使用库 stringr 的一种方法:

a <- c('11.25.16', '25.84.78', '78.26.99')

str_split(a, "\\.")

这会给你一个列表

> str_split(a, "\\.")
[[1]]
[1] "11" "25" "16"

[[2]]
[1] "25" "84" "78"

[[3]]
[1] "78" "26" "99"

我试图根据给出的新信息解决你的问题,所以我为你写了一个丑陋的函数:

extractor <- function(string) {
  tmp <- vector()
  if (grepl("^(c[[:punct:]]{2}\\d\\d\\.\\d\\d\\.\\d\\d)", string)) {
    tmp <- string %>% 
          str_extract("^(c[[:punct:]]{2}\\d\\d\\.\\d\\d\\.\\d\\d)") %>%
          str_extract("\\d\\d\\.\\d\\d\\.\\d\\d") %>%
          str_split("\\.")
    tmp <-  paste0("c('", tmp[[1]][1],"', '", tmp[[1]][2], "', '", tmp[[1]][3],"')")
  } else {
    tmp <- string %>%
      str_extract("^(\\d\\d)")
  }
  return(tmp)
}

我想你必须使用

df$new_line <- df$codes %>% lapply(extractor) %>% unlist

【讨论】:

  • 感谢您的建议,我尝试使用代码 dt$classification_codes &lt;- lapply(str_split(dt$codes, "\\.")) 这样做。但我得到一个错误:match.fun(FUN) 中的错误:缺少参数“FUN”,没有默认值
  • 使用lapply(),您的代码应如下所示:lapply(a, str_split, "\\.")。但只需删除 lapply 即可获得您想要的结果。
  • 谢谢!它实际上几乎解决了问题!我现在需要弄清楚如何只获取拆分代码的第一个字符。但我想经过一段时间的思考我就能做到
  • 添加了一些代码。也许它现在可以解决您的问题。
  • 谢谢!您之前的建议确实有助于解决我一直在努力解决的问题。但是,此功能不起作用。有人建议我在使用您的代码得到的输出上使用dt$col2 &lt;- sapply(dt$col1,function(x){sapply(x,'[',1)})。这样就可以了
猜你喜欢
  • 2018-03-21
  • 2022-11-16
  • 1970-01-01
  • 2016-03-04
  • 1970-01-01
  • 1970-01-01
  • 2021-07-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多