【问题标题】:Split a string and return the unique values [closed]拆分字符串并返回唯一值[关闭]
【发布时间】:2022-01-08 04:00:21
【问题描述】:

我有一个这样的字符串列表:

D<-c("0,0,0,0,0,0,0", "0,0,0,0,0,0,0,", "0,20,0,0,0,30,0", "0,60,61,70,0,0,","0,1,1,0,0,0,0,")

我想最终得到一个精简版本,每个字符串只有唯一值。

D2<-c("0","0","0,20,30","0,60,61,70","0,1")

我尝试使用 strsplit 和 unique 的组合进行循环,但最终得到了一堆 NA。

【问题讨论】:

  • strsplitunique 似乎是可行的 - sapply(strsplit(D,","), function(x) paste(unique(x),collapse=",") ) 是否适用于您的真实示例? - 我不知道你是如何获得 NA 值的。
  • 字符串中的第二个和第四个值以“,”结尾。这就是执行 strsplit 时出现 NA 的原因。
  • 您的解决方案在后期邮件中效果很好,值得正确回答
  • @AdamQuek - 这不是真的 - strsplit("0,0,0,0,0,0,0,", ",") 不会生成空白或 NA

标签: r string unique strsplit


【解决方案1】:

使用在 stringr 和其他包中定义的管道运算符 %>%

library(stringr)
D<-c("0,0,0,0,0,0,0", "0,0,0,0,0,0,0,", "0,20,0,0,0,30,0", "0,60,61,70,0,0,","0,1,1,0,0,0,0,")
result <-  D %>% sapply(strsplit, ",")  %>% sapply(unique) %>% sapply(paste, collapse=",") 

D2<-c("0","0","0,20,30","0,60,61,70","0,1")
all(D2 == result)

# [1] TRUE

【讨论】:

  • 请注意 stringr::str_split()strsplit 在尾随逗号的处理上有所不同:stringr::str_split("0,", ",") 返回一个包含两个元素向量 "0", "" 的列表,而 strsplit 只返回一个元素 @ 987654327@。您已通过删除尾随逗号来操作输入数据D,以返回预期结果。
  • @UweBlock,我应该注意到这个变化。我已经恢复到 strsplit 和原始数据
【解决方案2】:

这个问题已经吸引了三个答案,但即将关闭。恕我直言,thelatemail 在his comment 中提供的最佳解决方案将会丢失:

sapply(strsplit(D, ","), function(x) paste(unique(x), collapse = ","))
#[1] "0"          "0"          "0,20,30"    "0,60,61,70" "0,1" 

数据

由 OP 给出:

D < -c("0,0,0,0,0,0,0", "0,0,0,0,0,0,0,", "0,20,0,0,0,30,0", "0,60,61,70,0,0,","0,1,1,0,0,0,0,")

基准测试

一个小基准

library(stringr)
microbenchmark::microbenchmark(
  thelatemail = sapply(strsplit(D, ","), function(x) paste(unique(x), collapse = ",")),
  epi99 = D %>% sapply(str_split, ",")  %>% sapply(unique) %>% sapply(paste, collapse=","),
  trungnt37 = {
    out <- c()
    for(i in 1:length(D)){
      k <- strsplit(x = D[i], split = ",")
      m <- paste(unique(unlist(k)), collapse = ",")
      out <- c(out, m)
    }
    out
  }
)

表明thelatemail的回答是最快的:

#Unit: microseconds
#        expr     min       lq      mean   median      uq     max neval
# thelatemail  57.770  61.9240  72.63590  67.9655  75.705 151.789   100
#       epi99 318.679 338.5020 383.76284 362.6670 410.054 781.972   100
#   trungnt37  74.384  81.3695  96.77465  87.7885 102.702 240.897   100

请注意,epi99's stringr approach 不会返回预期结果,因为它有尾随逗号。

【讨论】:

    【解决方案3】:

    你应该使用 strsplit 和 unlist 函数。试试看代码

    out <- c()
    
    for(i in 1:length(d)){
        k <- strsplit(x = d[i], split = ",")
        m <- paste(unique(unlist(k)), collapse = ",")
        out <- c(out, m)
    }
    

    【讨论】:

      猜你喜欢
      • 2020-02-15
      • 1970-01-01
      • 2019-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-05
      相关资源
      最近更新 更多