cSplit库(splitstackshape)总是丢弃列

时间:2015-05-13 06:45:19

标签: r splitstackshape

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

问题现在是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版本

2 个答案:

答案 0 :(得分:10)

&#34; long&#34; format使用list(unlist(...))在&#34; data.table&#34;内修改了适当的列,并使用:=进行了分配。因此,如果使用drop,您将拆分该列,然后将其删除!

我会尝试在drop仅针对wide格式的文档中明确说明,或者如果用户尝试使用{{1}则添加message以长格式。随意file a FR or submit a PR

解决方法是分配另一列(例如&#34; a_orig&#34;)然后进行拆分:

drop

我还没有经过广泛的测试,但可能的解决办法是:

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"时更改输入数据集。这类似于您的想法,但可能是集成到实际包中的解决方案,在line 94附近。在这种情况下,只需要drop = FALSE部分。

答案 1 :(得分:0)

感谢您的反馈,我写了一个小功能作为解决方法。 我必须将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)