【问题标题】:How to prevent data.table to force numeric variables into character variables without manually specifying these?如何防止 data.table 将数字变量强制转换为字符变量而不手动指定这些?
【发布时间】:2015-07-22 16:08:36
【问题描述】:

考虑以下数据集:

dt <- structure(list(lllocatie = structure(c(1L, 6L, 2L, 4L, 3L), .Label = c("Assen", "Oosterwijtwerd", "Startenhuizen", "t-Zandt", "Tjuchem", "Winneweer"), class = "factor"), 
                 lat = c(52.992, 53.32, 53.336, 53.363, 53.368), 
                 lon = c(6.548, 6.74, 6.808, 6.765, 6.675), 
                 mag.cat = c(3L, 2L, 1L, 2L, 2L), 
                 places = structure(c(2L, 4L, 5L, 6L, 3L), .Label = c("", "Amen,Assen,Deurze,Ekehaar,Eleveld,Geelbroek,Taarlo,Ubbena", "Eppenhuizen,Garsthuizen,Huizinge,Kantens,Middelstum,Oldenzijl,Rottum,Startenhuizen,Toornwerd,Westeremden,Zandeweer", "Loppersum,Winneweer", "Oosterwijtwerd", "t-Zandt,Zeerijp"), class = "factor")),
            .Names = c("lllocatie", "lat", "lon", "mag.cat", "places"), 
            class = c("data.table", "data.frame"), 
            row.names = c(NA, -5L))

当我想将最后一列中的字符串拆分为单独的行时,我使用(data.table 版本 1.9.5+):

dt.new <- dt[, lapply(.SD, function(x) unlist(tstrsplit(x, ",", fixed=TRUE))), by=list(lllocatie,lat,lon,mag.cat)]

但是,当我使用:

dt.new2 <- dt[, lapply(.SD, function(x) unlist(tstrsplit(x, ",", fixed=TRUE))), by=lllocatie]

我得到了相同的结果,除了所有列都被强制为字符变量。问题在于,对于小型数据集,在 by 参数中指定不必拆分的变量并不是一个大问题,但对于具有许多列/变量的数据集来说,这是一个大问题。我知道可以使用splitstackshape 包(正如@ColonelBeauvel in his answer 提到的那样)来执行此操作,但我正在寻找data.table 解决方案,因为我想将更多操作链接到此。

如果不手动指定不必在 by 参数中拆分的变量,如何防止这种情况发生?

【问题讨论】:

  • tstrsplit() 使用type.convert=TRUE 参数。
  • 如果是指定很多变量的问题,你能用setdiff(names(dt),badcol)之类的东西来构造你的by.SD吗?
  • @Arun 有效(听起来像是一个答案:-))

标签: r data.table splitstackshape


【解决方案1】:

data.table 的两个解决方案:

1:按照@Arun 的建议,在tstrsplit() 中使用type.convert=TRUE 参数:

dt.new1 <- dt[, lapply(.SD, function(x) unlist(tstrsplit(x, ",", fixed=TRUE, type.convert=TRUE))), by=lllocatie]

2:在@Frank 提出的by 参数中使用setdiff(names(dt),"places")

dt.new2 <- dt[, lapply(.SD, function(x) unlist(tstrsplit(x, ",", fixed=TRUE))), by=setdiff(names(dt),"places")]

两种方法的结果相同:

> identical(dt.new1,dt.new2)
[1] TRUE

第二种解决方案的优点是,当您有多个包含字符串值的列时,只有您在 setdiff(names(dt),"places") 中指定的列被拆分(假设您只想要那个特定的列,在本例中为 places)分裂)。 splitstackshape 包也提供了这一优势。

【讨论】:

    【解决方案2】:

    这正是来自splitstackshape 包的cSplit 的工作:

    library(splitstackshape)
    
    cSplit(dt, 'places', ',')
    

    【讨论】:

    • 谢谢,我知道我可以用splitstackshape 做到这一点(但忘了在问题中提到这一点),但想要一个data.table 解决方案,因为想要链接更多的东西(+1不过)。
    • @Jaap splitstackshape 是一个基于 data.table 的包。但当然 Arun 提供了正确的答案。我很惊讶你不知道这一点,因为我们讨论了这个多星期,当时我最终提交了关于 type.convert 的错误报告,最终将在 R 的下一个版本中修复:)
    • @Jaap,如果你可以导入data.table,你可以导入splitstackshape!并且可以在 cSplit 之后进行链式操作!
    • 不知道splitstackshape 是一个基于data.table 的包。因此,您可以在cSplit 之后链接操作是合乎逻辑的。我认为这是一个学习时刻:-)
    猜你喜欢
    • 1970-01-01
    • 2023-02-21
    • 2016-11-29
    • 1970-01-01
    • 2019-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-24
    相关资源
    最近更新 更多