同时使用fread的colClasses和select参数

3
我将使用data.table软件包中的fread功能从一个包含许多未使用字段的制表符分隔文件中加载少量字段。为此,我将使用select选项,该选项可读入列。然而,如果我不指定各个字段的类别,则自动选择器无法工作(大部分/全部数值变量最终被读入为数值微小的数字,例如1.896916e-316)。为了解决这个问题,我的第一个直觉是将代码从以下方式更改:
DT <- fread("data.txt", select = c ("V1", "V2", ..., "Vn"))

to

DT <- fread("data.txt", select = c("V1", "V2", ..., "Vn"),
            colClasses = c("numeric", ..., "character"))

即,将select字符向量与相同长度的colClasses字符向量匹配,显然从所选集合中选择的第i个字段的类型等于colClasses的第i个元素。

然而,即使使用selectfread似乎并不喜欢这样做,colClasses仍需要一个具有与整个文件一样多字段的字符向量:

Error in fread("data.txt", select = c("V1", "V2", ..., "Vn", : colClasses未命名且长度为25但有256列。请参见?data.table了解colClasses用法。

如果我只需在一个文件上执行此操作,那么这可能是可以接受的——我会简单地使用"character"(或者其他类型)填充其余的字符向量,因为它们被抛弃了。

然而,我计划在与其他年份对应的文件上重复此过程13次左右——它们具有相同的列名称,但可能以不同的顺序出现(并且每年的列数也不同),这破坏了循环性(以及需要更长的时间)。

以下方法可行,但从编码角度来看并不高效:

DT <- fread("data.txt", select=c("V1", "V2", "V3"),
            colClasses = c(V1 = "factor", V2 = "character", V3 = "numeric"))

这很麻烦,因为我正在使用25列,所以需要大量的代码来指定列类型。我无法利用rep来节省空间,例如:

colClasses = c(rep("character", times = 3), rep("numeric", times = 20))

任何改进这个页面的建议吗?这是数据的预览参考:
         LEAID FIPST                                                   NAME SCHLEV AGCHRT CCDNF GSLO   V33  TOTALREV  TFEDREV
    1: 0100002    01                                 ALABAMA YOUTH SERVICES      N      3     1   03     0        -2       -2
    2: 0100005    01                                       ALBERTVILLE CITY     03      3     1   PK  4143  38394000  6326000
    3: 0100006    01                                        MARSHALL COUNTY     03      3     1   PK  5916  58482000 11617000
    4: 0100007    01                                            HOOVER CITY     03      3     1   PK 13232 154703000 10184000
    5: 0100008    01                                           MADISON CITY     03      3     1   PK  8479  89773000  6648000
---                                                                                                                       
18293: 5680180    56                                NORTHEAST WYOMING BOCES     07      3     1    N    -2        -2       -2
18294: 5680250    56                                         REGION V BOCES     07      3     1    N    -2        -2       -2
18295: 5680251    56                  WYOMING DEPARTMENT OF FAMILY SERVICES     02      3     1   KG    82        -2       -2
18296: 5680252    56 YOUTH EMERGENCY SERVICES, INC. - ADMINISTRATION OFFICE      N      3     1   07    29        -1       -1
18297: 5680253    56                           WYOMING BEHAVIORAL INSTITUTE      N      N     1   01     0        -2       -2

我认为在colClasses中有一个处理“NULL”参数的机制,从而避免了使用select的需要。 - IRTFM
2个回答

3

在仔细阅读Dowle先生在这里drop/select/colClasses选项的说明后,我找到了解决方案:

DT <- fread("data.txt", select = c("V1", "V2", "V3"),
            colClasses = list(character = c("char_names"),
                              factor = c("factor_names"),
                              numeric = c("numeric_names")))

由于我的.csv文件格式不正确,导致我的fread尝试存在其他问题,因此我之前没有意识到这一点。

尽管如此,我还是倾向于称其为一个bug,因为自然的方法并不能奏效:

DT <- fread("data.txt", select = c("V1", ..., "Vn"),
            colClasses = c("type1", ..., "typen"))

1
也许是这样的内容:

或许是沿着这些线路:

 varnames <- readLines(file='filename.txt', n=1)
 valid <- c("LEAID", "FIPST", "NAME", "SCHLEV", "AGCHRT", "CCDNF", "GSLO", "V33", "TOTALREV", "TFEDREV")
 colC <- varnames %in% valid 
 colCchar <- colC
 colCchar[!colC] <-"NULL"
 colCchar[colC] <- c( rep("numeric", 2), rep("character",2),  
                      rep("numeric", 2), "character",
                      rep("numeric", 3) )
 dt<-fread("data.txt", colClasses=colCchar)

显然,由于未提供200+第一行,因此未经测试。如果目标变量的顺序变化,它将不稳定,但是您的问题描述“还有待改进”。我无法完全理解列名称如何相同但会变化。您可能需要使用match来获取所需变量的顺序。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接