使用 R 转换 Excel 文件中存储为文本的数字

问题描述 投票:0回答:2

我想将R中的数据输出到excel文件,并且一直在使用openxlsx包。

writeDataTable是我一直在使用的函数。问题是我希望其中一列的条目是数字和文本的混合。由于 R 中数据帧的列必须具有所有相同类型的条目,因此所有内容都会转换为字符条目。

当我打开输出的 Excel 文件时,我会在数字单元格的角落看到绿色的小三角形,告诉我它们是存储为文本的数字,并让我可以选择转换为数字。

我想知道是否可以让 R 在保存文件之前创建的工作簿对象中为我转换它。

我花了很多时间在谷歌上搜索这个问题,寻找可能有帮助的不同库,但到目前为止还没有找到任何东西。我在下面有一个例子。请注意,这不是我使用的确切数据框,而是用于演示目的。

df = data.frame(A = c('Dog', '5', '7.04'), B = c('Cat', '12', '1.23'))
wb = createWorkbook()
addWorksheet(wb, "Sheet2")
writeDataTable(wb, "Sheet2", df)
output_file = "C:\\Users\\johndoe\\documents\\excel_file.xlsx"
saveWorkbook(wb, output_file)

任何帮助将不胜感激。

r excel openxlsx
2个回答
3
投票

这里有一个方法,但是速度会非常慢。

### unchanged
library(openxlsx)
df = data.frame(A = c('Dog', '5', '7.04'), B = c('Cat', '12', '1.23'))
wb = createWorkbook()
addWorksheet(wb, "Sheet2")
writeDataTable(wb, "Sheet2", df)

### this is the new part
for (cn in seq_len(ncol(df))) {
  for (rn in seq_len(nrow(df))) {
    if (!is.numeric(df[rn,cn]) && !is.na(val <- as.numeric(as.character(df[rn,cn])))) {
      writeData(wb, "Sheet2", val, startCol = cn, startRow = 1L + rn)
    }
  }
}

### unchanged
saveWorkbook(wb, output_file)

问题是这是一次写入一个单元格。

改善此问题的方法:

  • 如果数字多于字符串,您可能需要通过使用

    as.numeric
    转换相关列(产生大量
    NA
    )来稍微扭转这一点,然后逐一覆盖单元格的
    NA
    与前一个字符串的值。

  • 您可以查找要替换的单元格运行(也许在列中使用

    rle
    ),这将逐个簇而不是逐个单元地写入。


0
投票

可以完成一种更具可扩展性的解决方法,类似于@MKa建议的方法,其中涉及将 R 中的数据帧值修改为公式:

library(openxlsx)
df <- data.frame(A = c('Dog', '5', '7.04'), B = c('Cat', '12', '1.23'))
wb <- createWorkbook()
addWorksheet(wb, "Sheet2")

# Modify df vals to formula class
df$A <- ifelse(!is.na(as.numeric(df$A)), 
           df$A,
           paste0("=\"", df$A, "\""))
class(df$A) <- "formula"
df$B <- ifelse(!is.na(as.numeric(df$B)), 
           df$B,
           paste0("=\"", df$B, "\""))
class(df$B) <- "formula"

writeDataTable(wb, "Sheet2", df)
saveWorkbook(wb, 'excel_file.xlsx', overwrite = T)

主要警告是使用 openxlsx 读取同一文件时出现问题:

使用 writeFormula 写入 Workbook 对象的公式将不会被 read.xlsx() 获取。这是因为在 Excel 中打开文件时只编写了公式并进行计算。使用 Excel 打开、保存和关闭文件即可解决此问题。

有一些解决方案可以仍然使用其他库来读取文件,但可能并不理想:

© www.soinside.com 2019 - 2024. All rights reserved.