【问题标题】:cSplit library(splitstackshape) is always dropping the columncSplit library(splitstackshape) 总是丢弃列
【发布时间】:2015-05-13 06:45:19
【问题描述】:

我正在寻找一种通过分隔符拆分列内容并将表格转换为长格式的方法。我从splitstackshape 包中找到了cSplit,它几乎可以满足我的要求。

问题现在与drop 选项有关。我希望以某种方式复制我的拆分列,但这不会发生。我做错了吗?有人遇到过这个问题吗?

我不确定我是否做错了什么,但drop = FALSE 选项在我的情况下不起作用。

这是一个例子:

library(splitstackshape)
jnk <- data.table(a = '1,2,3,4,5', b = 5)
jnk
#            a b
# 1: 1,2,3,4,5 5

cSplit(jnk, 'a', ',', 'long', drop = FALSE)
#    a b
# 1: 1 5
# 2: 2 5
# 3: 3 5
# 4: 4 5
# 5: 5 5

我的预期是这样的:

cSplit(jnk, 'a', ',', 'long', drop = FALSE)
#    a b    a.orig
# 1: 1 5 1,2,3,4,5
# 2: 2 5 1,2,3,4,5
# 3: 3 5 1,2,3,4,5
# 4: 4 5 1,2,3,4,5
# 5: 5 5 1,2,3,4,5

我使用的是 1.4.2 版

【问题讨论】:

  • 如果 df 中有更多行,这肯定不起作用,因为 jnk[['a']] 需要具有相同的长度,否则每次都会附加......所以它不适用于 @ 987654328@

标签: r splitstackshape


【解决方案1】:

“长”格式使用“data.table”中的list(unlist(...)) 修改列,并分配有:=。因此,如果使用drop,您将拆分列然后将其删除!

我将尝试在文档中明确说明drop 仅适用于wide 格式,或者如果用户尝试以长格式使用drop,则添加message。欢迎随时file a FR or submit a PR

解决方法是分配另一列(例如“a_orig”),然后进行拆分:

jnk <- data.table(a=c('1,2,3,4,5','1,2,3','2,3'),b=c(5,4,3))
cSplit(jnk[, a_orig := a], "a", ",", "long")
#     a b    a_orig
#  1: 1 5 1,2,3,4,5
#  2: 2 5 1,2,3,4,5
#  3: 3 5 1,2,3,4,5
#  4: 4 5 1,2,3,4,5
#  5: 5 5 1,2,3,4,5
#  6: 1 4     1,2,3
#  7: 2 4     1,2,3
#  8: 3 4     1,2,3
#  9: 2 3       2,3
# 10: 3 3       2,3

我没有进行广泛的测试,但可能的解决方法是:

cSplit2 <- function(indt, splitCols, sep = ",", direction = "wide", 
                    fixed = TRUE, drop = TRUE, stripWhite = TRUE, 
                    makeEqual = NULL, type.convert = TRUE) {
  if (direction == "long" & !drop) {
    indt <- as.data.table(indt)
    indt[, `:=`(eval(paste(splitCols, "orig", sep = "_")),
                lapply(splitCols, function(x) indt[[x]]))]
  }
  cSplit(indt, splitCols, sep, direction, fixed, drop, stripWhite, 
         makeEqual, type.convert)
}

基本思想是仅在direction == "wide"drop = FALSE 时更改输入数据集。这与您的想法相似,但可能是集成到实际包中的解决方案,大约在line 94 附近。在这种情况下,应该只需要 indt[, `:=`(eval(paste(splitCols, "orig", sep = "_")), lapply(splitCols, function(x) indt[[x]]))] 部分。

【讨论】:

    【解决方案2】:

    感谢您的反馈,我写了一个小函数作为解决方法。 我必须将data.table 更改为data.frame 才能使其正常工作。对于data.table,我需要设置一个附加参数,但它会因data.frame 而崩溃。就我而言,我大部分时间都需要data.frame,因此我对其进行了优化。

    library(splitstackshape)
    jnk <- data.frame(a = c('1,2,3,4,5','1,2,3','2,3'),
                      b = c('a,b,c,d,e','a,b,c','a,b'),
                      c = c(5,4,3))
    jnk
    
    myCSplit <- function(data_set, splitCols, sep = ',', direction = 'long', drop = TRUE, ...) {
      if(direction == 'long' & !drop) {
        orig_names <- sub('$', '_orig', splitCols)
        df <- as.data.frame(data_set[,splitCols])
        names(df) <- orig_names
        df2 <- cbind(data_set, df)
        return(cSplit(df2, splitCols, sep, 'long'))
      } else {
        return(cSplit(data_set, splitCols, sep, direction, drop = drop,...))
      }
    }
    myCSplit(jnk, 'a', ',')
    myCSplit(jnk, 'a', ',', drop = FALSE)
    myCSplit(jnk, 'a', ',', 'wide')
    myCSplit(jnk, 'a', ',', 'wide', drop = FALSE)
    myCSplit(jnk, c('a','b'), ',', 'long', drop = FALSE)
    

    【讨论】:

    • 嘿@AnandaMahto 也许你可以将此功能添加到下一个版本中......在我的情况下它会非常有用。
    • 据我所知,我应该只用一行就可以解决问题。不过我得做一些测试才能看到。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多