0

我有一个很大的data.frame(1.9M 记录,有 20 列)。其中一列是具有不同长度的数字值的因子列(不同数量的字符/数字,例如 567839、234324324、3243211 等)注意:这些是数字代码,没有实际值,也可能只是不同的字符这个例子的长度。

现在我想将 do 因子转换为 13 位因子,这样在位数小于 13 的情况下,因子会在零之前。

例子:

Old factor      Length  New factor
432543532532    12      0432543532532
3285087250932   13      3285087250932
464577534       9       0000464577534
2225324324324   13      2225324324324
864235325264    12      0864235325264

我尝试了不同的方法,但现在我被卡住了。问题是因子的长度在整个数据集中都不同。

我尝试了以下方法,并举了一个例子。

data.frame使用我执行代码的三个不同列进行创建,以识别问题。

> df.test <- as.data.frame(cbind(c("432543532532", "3285087250932", "464577534", "2225324324324", "864235325264"), c("3285087250932", "132543532532", "464577534", "2225324324324", "864235325264"), c("164577534", "3285087250932", "432543532532", "2225324324324", "864235325264")))
> df.test
             V1            V2            V3
1  432543532532 3285087250932     164577534
2 3285087250932  132543532532 3285087250932
3     464577534     464577534  432543532532
4 2225324324324 2225324324324 2225324324324
5  864235325264  864235325264  864235325264

> levels(df.test$V1) <- paste(substr("0000000000000", 0, 13 - nchar(as.character(levels(df.test$V1)))), levels(df.test$V1), sep = '')
> levels(df.test$V2) <- paste(substr("0000000000000", 0, 13 - nchar(as.character(levels(df.test$V2)))), levels(df.test$V2), sep = '')
> levels(df.test$V3) <- paste(substr("0000000000000", 0, 13 - nchar(as.character(levels(df.test$V3)))), levels(df.test$V3), sep = '')
> df.test
             V1             V2                V3
1  432543532532 03285087250932     0000164577534
2 3285087250932  0132543532532 00003285087250932
3     464577534     0464577534  0000432543532532
4 2225324324324 02225324324324 00002225324324324
5  864235325264  0864235325264  0000864235325264

问题是代码nchar(as.character(levels(df.test$V1)))不使用向量的长度,df.test$V1而只使用一个值;因子的第一级的长度(在字母/升序上)。它对所有记录执行必要的前面零的数量。所以没有矢量代码!

注意:如果我单独运行“nchar”代码,它会给我一个包含所有记录长度的向量,所以我认为它应该可以工作......

> nchar(as.character(levels(df.test$V1)))
[1] 13 13 12  9 12
> nchar(as.character(levels(df.test$V2)))
[1] 13 14 14 10 13
> nchar(as.character(levels(df.test$V3)))
[1] 13 17 17 16 16

为什么不nchar(as.character(levels(df.test$V1)))作为矢量运算符运行?谁能告诉我如何更改我的代码,以便得到正确的结果?

提前致谢!

注意。请注意,在实际情况下,我只需要对data.frame.

4

3 回答 3

5

对于零填充,您可以使用sprintf('%04d', 1:5),但示例中的代码必须是数字。

max.nchar <- max(nchar(levels(df.test$V1)))

sprintf(paste0('%0',max.nchar), as.numeric(levels(df$V1))[df$V1])

也许有更好的方法......但你可以使用gsubwith sprintf

gsub(' ', '0', sprintf('%04s', levels(factor(10:15))))
于 2012-04-24T14:59:07.110 回答
1
as.data.frame( lapply(df.test, sprintf, fmt="%013s"))
#---------------------    
         V1            V2            V3
1 0432543532532 3285087250932 0000164577534
2 3285087250932 0132543532532 3285087250932
3 0000464577534 0000464577534 0432543532532
4 2225324324324 2225324324324 2225324324324
5 0864235325264 0864235325264 0864235325264
于 2012-04-24T15:43:32.613 回答
0

您的代码无法正常工作,因为返回“与(在可能的强制之后)substr具有相同长度和相同属性的字符向量”。x因此,您必须确保x具有与预期返回值一样多的元素

df.test <- as.data.frame(cbind(c("432543532532", "3285087250932", "464577534", "2225324324324", "864235325264"), c("3285087250932", "132543532532", "464577534", "2225324324324", "864235325264"), c("164577534", "3285087250932", "432543532532", "2225324324324", "864235325264")))
df.test

n <- nrow(df.test)
start <- rep(0, n)
padStrs <- rep("0000000000000", n)
for (thevar in colnames(df.test))) {
    cdiff1 <- 13 - nchar(as.character(levels(df.test[, thevar])))
    levels(df.test[, thevar]) <- paste(substr(padStrs, 0, cdiff), levels(df.test[, thevar]), sep = '')
}
于 2012-04-25T09:19:02.293 回答