【问题标题】:Conditional string splitting条件字符串拆分
【发布时间】:2014-07-27 11:36:49
【问题描述】:

我的问题类似于conditional string splitting in R (using tidyr)。但是,我需要拆分超过 2 列。如果数据集列是

             cost
        reed_cost
   cost of living
        reed cost
 id gene_id locus

如何将其分成四列

col1 col2 col3   col4
                 cost
          reed   cost
     cost   of living
          reed   cost
  id gene   id  locus

我尝试了链接中的解决方案,但无法正确解决。

【问题讨论】:

  • 你真的需要这样拆分吗(初始列是空的)?

标签: r tidyr


【解决方案1】:
dat <- data.frame(V1 = c("cost", "reed_cost", "cost of living", "reed cost", "id gene_id locus")) # Your data

library(stringr)
vars <- str_split_fixed(dat$V1, " |_", max(str_count(dat$V1, " |_") + 1))
dat2 <- data.frame(t(apply(vars, 1, function(x) c(x[x == ""], x[x != ""]))))
names(dat2) <- paste0("col", seq_len(dim(dat2)[2]))

#   col1 col2 col3   col4
# 1                  cost
# 2           reed   cost
# 3      cost   of living
# 4           reed   cost
# 5   id gene   id  locus

【讨论】:

    【解决方案2】:

    这里有两个选项应该可以很好地扩展。您需要加载“data.table”和“reshape2”,以及my cSplit function

    library(data.table)
    library(reshape2)
    library(devtools)
    source_gist(11380733) ## For cSplit
    

    第一个假设您实际上不需要将值浮动到最右边的列。

    cSplit(X, "x", sep = " |_", fixed = FALSE)
    #     x_1  x_2    x_3   x_4
    # 1: cost   NA     NA    NA
    # 2: reed cost     NA    NA
    # 3: cost   of living    NA
    # 4: reed cost     NA    NA
    # 5:   id gene     id locus
    

    第二个假设你想要你显示的表单中的数据:

    dcast.data.table(                       # for long to wide
      cSplit(cbind(rn = 1:nrow(X), X),      # start by splitting into a long form
             "x", sep = " |_", "long", 
             fixed = FALSE)[, 
         n := sequence(.N), by = rn][,      # sequence by row-name
         n := abs(n-max(n))+1],             # ^^ reversed
      rn ~ n, value.var = "x", fill = "")   # formula for casting
    #    rn     1      2    3    4
    # 1:  1                   cost
    # 2:  2              cost reed
    # 3:  3       living   of cost
    # 4:  4              cost reed
    # 5:  5 locus     id gene   id
    

    【讨论】:

      【解决方案3】:

      这是一个基本解决方案。我们拆分输入并反转每行的元素。然后我们将每行的长度设置为最大长度并将它们反转回来:

      # test data
      x <- c("cost", "reed_cost", "cost of living", "reed cost", "id gene_id locus")
      
      s <- lapply(strsplit(x, "[ _]"), rev)
      t(sapply(lapply(s, "length<-", max(sapply(s, length))), rev))
      

      给出这个矩阵:

           [,1] [,2]   [,3]   [,4]    
      [1,] NA   NA     NA     "cost"  
      [2,] NA   NA     "reed" "cost"  
      [3,] NA   "cost" "of"   "living"
      [4,] NA   NA     "reed" "cost"  
      [5,] "id" "gene" "id"   "locus" 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-23
        • 1970-01-01
        • 1970-01-01
        • 2015-06-08
        • 2017-06-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多