无法使用 readr 阻止因子列中空单元格的 NA
can't prevent NAs for empty cells in factor columns using readr
我正在尝试读取包含一些空单元格的文件并获取预期的空单元格 NA
。
我有一些特殊的列,它们的值只能是 ''
或 '+'
。所以我想通过使用
将这些列设置为因子 class
read_tsv('file.txt',
col_types=list(
column_with_empty_cells=col_factor(c('','+'))))
但该列在这些列中仍然有 NAs
。我可以通过更改 na
参数来更改 readr_tsv
函数的全局行为,但这不是我想要的。我只想在特定列中更改它。
有没有办法把这些NAs
直接转换成''
?之后我肯定可以这样做,但我想知道我是否以错误的方式使用了这个东西。
编辑
这是一个test file
我如何实际上传文件?我只能附上图片...
根据 readr
的文档,没有为列的子集传递多个 na 参数的实现,只有一个全局规范。我认为这在需要计算效率时最为突出。对于这些情况,可能值得多次调用 read_tsv
指定要使用 na 参数规范读取的列的子集并跳过所有其他列。然后对具有不同 na 参数的列的其他子集重复该过程,并只读取应使用该 na 参数解析的列。最后,可以 cbind
多个数据帧。
尚未向 readr
开发人员提出此问题。如果您希望将其作为增强功能提交,请随时通过在项目存储库中生成一个新问题来提交:Readr.
您可以使用 lapply
和 factor
创建一个新函数来解决此问题:
library(readr)
read_tsv2 <- function(file, na.char=" "){
test <- read_tsv(file = file, col_types=list(column_with_empty_cells=col_character()))
test <- as.data.frame(test)
names_tsv <- names(test)
test <- lapply(test,
function(x){
if(sum(is.na(x))!=length(x)){
x[is.na(x)] <- na.char
factor(x,levels = unique(x))
}else{
x
}
}
)
test <- do.call(cbind.data.frame, test)
names(test) <- names_tsv
test
}
file <- read_tsv2(file = "~/Downloads/file.txt", na.char = " ")
file
test column_with_empty_cells
1 <NA>
2 <NA>
3 <NA>
4 <NA>
5 <NA>
6 <NA>
7 <NA>
8 <NA>
9 <NA>
10 <NA>
11 <NA>
12 <NA>
13 <NA>
14 <NA>
15 <NA>
16 <NA>
17 <NA>
18 <NA>
19 <NA>
20 <NA>
21 <NA>
22 <NA>
23 <NA>
24 <NA> +
25 <NA> +
26 <NA>
27 <NA>
28 <NA> +
read_tsv
是 read_delim
的自定义实现,read_csv
也是如此。 tsv
专门用于读取制表符分隔的文件,在本例中也是您的测试文件。如果您不依赖于使用特定的制表符分隔实现,则可以使用 read_csv
轻松解决您的问题。
read_csv
如果在列中发现很少的唯一字符集,默认情况下会将 class 作为因素。
获取值作为因子
read.csv("test.txt", sep = "\t")
获取值作为字符
read.csv("test.txt", sep = "\t", stringsAsFactors = FALSE)
Sample dataframe read
编辑 1
如果您希望将具有 " "
的特定列视为 NA
,您可以在阅读时仅使用 lappy 将 class 传递给那些列列表,但是基于关于你的问题,看起来你希望 NULL
被视为 NA 并且不应强制任何其他字符。
我正在尝试读取包含一些空单元格的文件并获取预期的空单元格 NA
。
我有一些特殊的列,它们的值只能是 ''
或 '+'
。所以我想通过使用
read_tsv('file.txt',
col_types=list(
column_with_empty_cells=col_factor(c('','+'))))
但该列在这些列中仍然有 NAs
。我可以通过更改 na
参数来更改 readr_tsv
函数的全局行为,但这不是我想要的。我只想在特定列中更改它。
有没有办法把这些NAs
直接转换成''
?之后我肯定可以这样做,但我想知道我是否以错误的方式使用了这个东西。
编辑 这是一个test file
我如何实际上传文件?我只能附上图片...
根据 readr
的文档,没有为列的子集传递多个 na 参数的实现,只有一个全局规范。我认为这在需要计算效率时最为突出。对于这些情况,可能值得多次调用 read_tsv
指定要使用 na 参数规范读取的列的子集并跳过所有其他列。然后对具有不同 na 参数的列的其他子集重复该过程,并只读取应使用该 na 参数解析的列。最后,可以 cbind
多个数据帧。
尚未向 readr
开发人员提出此问题。如果您希望将其作为增强功能提交,请随时通过在项目存储库中生成一个新问题来提交:Readr.
您可以使用 lapply
和 factor
创建一个新函数来解决此问题:
library(readr)
read_tsv2 <- function(file, na.char=" "){
test <- read_tsv(file = file, col_types=list(column_with_empty_cells=col_character()))
test <- as.data.frame(test)
names_tsv <- names(test)
test <- lapply(test,
function(x){
if(sum(is.na(x))!=length(x)){
x[is.na(x)] <- na.char
factor(x,levels = unique(x))
}else{
x
}
}
)
test <- do.call(cbind.data.frame, test)
names(test) <- names_tsv
test
}
file <- read_tsv2(file = "~/Downloads/file.txt", na.char = " ")
file
test column_with_empty_cells
1 <NA>
2 <NA>
3 <NA>
4 <NA>
5 <NA>
6 <NA>
7 <NA>
8 <NA>
9 <NA>
10 <NA>
11 <NA>
12 <NA>
13 <NA>
14 <NA>
15 <NA>
16 <NA>
17 <NA>
18 <NA>
19 <NA>
20 <NA>
21 <NA>
22 <NA>
23 <NA>
24 <NA> +
25 <NA> +
26 <NA>
27 <NA>
28 <NA> +
read_tsv
是 read_delim
的自定义实现,read_csv
也是如此。 tsv
专门用于读取制表符分隔的文件,在本例中也是您的测试文件。如果您不依赖于使用特定的制表符分隔实现,则可以使用 read_csv
轻松解决您的问题。
read_csv
如果在列中发现很少的唯一字符集,默认情况下会将 class 作为因素。
获取值作为因子
read.csv("test.txt", sep = "\t")
获取值作为字符
read.csv("test.txt", sep = "\t", stringsAsFactors = FALSE)
Sample dataframe read
编辑 1
如果您希望将具有 " "
的特定列视为 NA
,您可以在阅读时仅使用 lappy 将 class 传递给那些列列表,但是基于关于你的问题,看起来你希望 NULL
被视为 NA 并且不应强制任何其他字符。