使用不同编码读取Rdata文件

12

我有一个.RData文件需要在我的Linux(UTF-8)机器上读取,但我知道该文件是Latin1格式的,因为我已经在Windows上创建了它们。不幸的是,我没有访问原始文件或Windows机器的权限,我需要在我的Linux机器上读取这些文件。

要读取Rdata文件,正常的过程是运行load("file.Rdata")。像read.csv这样的函数有一个encoding参数,您可以使用它来解决这种问题,但是load没有此类功能。如果我尝试load("file.Rdata", encoding = latin1),我会得到这个(预期的)错误:

Error in load("file.Rdata", encoding = "latin1") : unused argument (encoding = "latin1")

我还能做什么?我的文件加载了包含音调的文本变量,在UTF-8环境中打开后会损坏。


3
RData 文件没有编码。您需要将序列化的 Rdata 加载到 R 工作区后,重新对值进行编码。如果阅读 ?Encoding 后仍不清楚,请执行加载操作,并发布 dput(head(object)) 的输出。 - IRTFM
@42,这似乎解决了问题,可惜显然我需要对数据框中的每个向量应用“编码(x)”。我会好好看看它并回复给你。 - Waldir Leoncio
您可以在加载前和加载后将名称记录在工作区中,然后针对具有字符值的项目处理差异。 - IRTFM
5个回答

8

得益于42的评论,我已经成功编写了一个重新编码文件的函数:

fix.encoding <- function(df, originalEncoding = "latin1") {
  numCols <- ncol(df)
  for (col in 1:numCols) Encoding(df[, col]) <- originalEncoding
  return(df)
}

这里的关键是命令Encoding(df[, col]) <- "latin1",它将数据框df的列col转换为latin1格式。不幸的是,Encoding只能接受列对象作为输入,因此我必须创建一个函数来扫描数据框对象的所有列并应用转换。
当然,如果你的问题只涉及几列,最好只对这些列应用Encoding而不是整个数据框(你可以修改上面的函数以接受一组列作为输入)。此外,如果你面临的是相反的问题,即将在Linux或Mac OS中创建的R对象读入Windows中,你应该使用originalEncoding = "UTF-8"

3

继上次回答后,这是一个小更新,使其适用于factors和dplyr的tibble。感谢您的启发。

fix.encoding <- function(df, originalEncoding = "UTF-8") {
numCols <- ncol(df)
df <- data.frame(df)
for (col in 1:numCols)
{
        if(class(df[, col]) == "character"){
                Encoding(df[, col]) <- originalEncoding
        }

        if(class(df[, col]) == "factor"){
                        Encoding(levels(df[, col])) <- originalEncoding
}
}
return(as_data_frame(df))
}

1
感谢您发布这篇文章。我稍作修改了您的函数,以防您有一些列是字符型而另一些列不是字符型。否则会出现错误:
> fix.encoding(adress)
Error in `Encoding<-`(`*tmp*`, value = "latin1") :
 a character vector argument expected

所以这是修改过的函数:
fix.encoding <- function(df, originalEncoding = "latin1") {
    numCols <- ncol(df)
    for (col in 1:numCols)
            if(class(df[, col]) == "character"){
                    Encoding(df[, col]) <- originalEncoding
            }
    return(df)
}

然而,这不会改变“因子”列中级别名称的编码。幸运的是,我发现了一种将数据框中所有因子更改为字符的方法(这可能不是最好的方法,但在我的情况下这是我所需要的):
i <- sapply(df, is.factor)
df[i] <- lapply(df[i], as.character)

0

使用dplyr的mutate_if另一个选项:

fix_encoding <- function(x) {
  Encoding(x) <- "latin1"
  return(x)
}
data <- data %>% 
  mutate_if(is.character,fix_encoding) 

对于需要重新编码的因子变量:

fix_encoding_factor <- function(x) {
  x <- as.character(x)
  Encoding(x) <- "latin1"
  x <- as.factor(x)
  return(x)
}
data <- data %>% 
  mutate_if(is.factor,fix_encoding_factor) 

0
这在Windows上也可能是一个问题,特别是对于在较旧版本的R(<4.2)中创建的文件。 为了避免这个问题,我使用以下代码来指定编码并重新保存文件(无需重新处理):
file <- "file.RData"
df.encoding <- "latin1"

# Load data.frame
df.name <- load(file) 
df <- get(df.name[1])

# Names
Encoding(names(df)) <- df.encoding

# Variable labels (if present)
if (!is.null(vlabels <- attr(df, "variable.labels"))) {
  Encoding(vlabels) <- df.encoding  
  Encoding(names(vlabels)) <- df.encoding
  attr(df, "variable.labels") <- vlabels  
}

# Character variables
vchar <- sapply(df, is.character)
df[vchar] <- lapply(df[vchar],  function(x) {
  Encoding(x) <- df.encoding
  x
})

# Factors
vcat <- sapply(df, is.factor)
df[vcat] <- lapply(df[vcat],  function(x) {
  Encoding(levels(x)) <- df.encoding
  x
})

# Save
assign(df.name[1], df)
save(list = df.name[1], file = file)

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