R,data.table:如何防止fread推断一列的NA



我有一个csv,它有一列包含字符串值。其中一个值是文本字符串NA,我想将其视为字符串。其他列有实际的NA,我想将其视为NA。我有没有办法指定fread不应该自动解析一列的NA?我尝试过使用colClasses参数,但这似乎不起作用。(我怀疑它是在自动解析NA之后运行转换的,而我正在寻找类似pandasconverters自变量的东西,它似乎在读取时执行强制转换。(

MWE:

test.csv:

strings,other.values
NA,blah
blah,NA

我想将strings中的NA读取为字符序列NA,但将other.values中的NA读取为值NA。

> library(data.table)
> df <- fread('test.csv', header=TRUE) # adding colClasses=c('strings'='character') doesn't help
> df
strings other.values                                                                                                       
1:    <NA>         blah                                                                                                       
2:    blah         <NA> 
> which(is.na(df), arr.ind=TRUE)
row col                                                                                                                  
[1,]   1   1                                                                                                                  
[2,]   2   2  

期望输出:

> df
strings other.values                                                                                                       
1:      NA         blah                                                                                                       
2:    blah         <NA> 
> which(is.na(df), arr.ind=TRUE)
row col                                                                                                                
[2,]   2   2

如果它是相关的,这里将其与Python的pandas进行比较,在这种情况下,它通过converters参数实现了我想要的功能(当然我想在R中做其他事情(。

>>> import pandas as pd
>>> df = pd.read_csv('test.csv')
>>> df
strings other.values                                                                                                        
0     NaN         blah                                                                                                        
1    blah          NaN 
>>> df.isnull()
strings  other.values                                                                                                      
0     True         False                                                                                                      
1    False          True
>>> df = pd.read_csv('test.csv', converters={'strings':str})
>>> df
strings other.values                                                                                                        
0      NA         blah                                                                                                        
1    blah          NaN
>>> df.isnull()
strings  other.values                                                                                                      
0    False         False                                                                                                      
1    False          True

编辑:当然,在这种简单的情况下,可以做这样的事情:

> library(dplyr)
> df <- df |> mutate(strings = case_when(is.na(strings) ~ 'NA', TRUE ~ strings))

但这似乎是一个破解,不能像我所希望的那样推广(例如,如果字符串列中有空格会被解析为NA,这会缩小差异(。

一个潜在的选择是在"字符串";具有预处理步骤的列,即

";test.csv":

strings,other.values
NA,blah
blah,NA
library(data.table)
df <- fread(cmd = "sed 's/^/"/;s/,/",/' ~/Desktop/test.csv", header = TRUE)
df
#>    strings other.values
#> 1:      NA         blah
#> 2:    blah         <NA>

如果";字符串";列在另一个位置,您可以调整sed命令以适应,例如。";test2.csv":

xx,yy,strings,other.values
1,string,NA,blah
2,test,blah,NA
df2 <- fread(cmd = "sed 's/,/,"/2;s/,/",/3' ~/Desktop/test2.csv", header = TRUE)
df2
#>    xx     yy strings other.values
#> 1:  1 string      NA         blah
#> 2:  2   test    blah         <NA>

最新更新