cSplit 库(splitstackshape)总是删除列
cSplit library(splitstackshape) is always dropping the column
我正在寻找一种通过分隔符拆分列内容并将 table 转换为长格式的方法。我从 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 版本
"long" 格式使用 "data.table" 中的 list(unlist(...))
修改了列,指定了 :=
。因此,如果使用 drop
,您将拆分该列,然后将其删除!
我将尝试在文档中明确说明 drop
仅适用于 wide
格式,或者如果用户尝试使用 [=14] 则添加 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]]))]
部分是必需的。
感谢您的反馈,我写了一个小函数作为解决方法。
我必须将 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)
我正在寻找一种通过分隔符拆分列内容并将 table 转换为长格式的方法。我从 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 版本
"long" 格式使用 "data.table" 中的 list(unlist(...))
修改了列,指定了 :=
。因此,如果使用 drop
,您将拆分该列,然后将其删除!
我将尝试在文档中明确说明 drop
仅适用于 wide
格式,或者如果用户尝试使用 [=14] 则添加 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]]))]
部分是必需的。
感谢您的反馈,我写了一个小函数作为解决方法。
我必须将 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)