【问题标题】:Incorrect Data Getting Written To CSV In R在 R 中将不正确的数据写入 CSV
【发布时间】:2019-07-20 19:11:39
【问题描述】:

我正在使用write.csvdata 下方写入csv,但是当我查看csv 文件时,文件中的数据与print()@@ 时得到的数据不同/更多987654327@ 到R 控制台。

有什么建议为什么会这样?

输入数据:数据

data <- structure(
  list(
    `A` = c(
      NA_character_,
      NA_character_,
      NA_character_,
      NA_character_,
      NA_character_
    ),
    `B` = c("-0.5", "-0.5", "-0.5", "-0.5", "-0.5"),
    `T` = c(
      NA_character_,
      NA_character_,
      NA_character_,
      NA_character_,
      NA_character_
    ),
    `C` = c(
      "4.5999999999999996",
      "4.5999999999999996",
      "4.5999999999999996",
      "4.5999999999999996",
      "2.4"
    ),
    `R` = c("V",
            "V", "V", "V", "V"),
    `D` = c(
      NA_character_,
      NA_character_,
      NA_character_,
      NA_character_,
      NA_character_
    ),
    `S` = c(
      NA_character_,
      NA_character_,
      NA_character_,
      NA_character_,
      NA_character_
    ),
    `E` = c(
      NA_character_,
      NA_character_,
      NA_character_,
      NA_character_,
      NA_character_
    ),
    `F` = c("Yes",
            "Yes", "Yes", "Yes", "Yes"),
    `G` = c("AA",
            "BB", "CC", "DD",
            "EE"),
    `H` = c(NA_real_, NA_real_, NA_real_,
            NA_real_, NA_real_),
    `I` = c(NA_real_, NA_real_, NA_real_,
            NA_real_, NA_real_),
    `J` = c(NA_real_, NA_real_, NA_real_,
            NA_real_, NA_real_),
    `K` = structure(
      c(
        NA_character_,
        NA_character_,
        NA_character_,
        NA_character_,
        NA_character_
      ),
      .Dim = c(5L, 1L)
    ),
    `L` = structure(
      c(
        NA_character_,
        NA_character_,
        NA_character_,
        NA_character_,
        NA_character_
      ),
      .Dim = c(5L, 1L)
    ),
    `M` = c(NA_real_, NA_real_,
            NA_real_, NA_real_, NA_real_),
    `N` = structure(
      c(
        NA_character_,
        NA_character_,
        NA_character_,
        NA_character_,
        NA_character_
      ),
      .Dim = c(5L, 1L)
    ),
    `O` = structure(list(
      KK = c(NA_real_,
             NA_real_, NA_real_, NA_real_, NA_real_)
    ), row.names = c(NA,
                     5L), class = "data.frame"),
    `P` = structure(list(
      JJ = c(NA_real_,
              NA_real_, NA_real_, NA_real_, NA_real_)
    ), row.names = c(NA,
                     5L), class = "data.frame")
  ),
  row.names = c(NA, 5L),
  class = "data.frame"
)

write.csv() 以上数据

write.csv(data, file = "data.csv", row.names = FALSE)

以上代码输出不正确

A   B   T   C   R   D   S   E   F   G   H   I   J   K   L   M   N   O   P                               
NA  -0.5    NA  4.6 V   NA  NA  NA  Yes AA  NA  NA  NA  NA  NA  NA  NA  c(NA     NA  NA  NA  NA)    c(NA     NA  NA  NA  NA)
NA  -0.5    NA  4.6 V   NA  NA  NA  Yes BB  NA  NA  NA  NA  NA  NA  NA  c(NA     NA  NA  NA  NA)    c(NA     NA  NA  NA  NA)
NA  -0.5    NA  4.6 V   NA  NA  NA  Yes CC  NA  NA  NA  NA  NA  NA  NA  c(NA     NA  NA  NA  NA)    c(NA     NA  NA  NA  NA)
NA  -0.5    NA  4.6 V   NA  NA  NA  Yes DD  NA  NA  NA  NA  NA  NA  NA  c(NA     NA  NA  NA  NA)    c(NA     NA  NA  NA  NA)
NA  -0.5    NA  2.4 V   NA  NA  NA  Yes EE  NA  NA  NA  NA  NA  NA  NA  c(NA     NA  NA  NA  NA)    c(NA     NA  NA  NA  NA)

print() 的期望输出

> print(data)
     A    B    T                  C R    D    S    E   F  G  H  I  J    K    L  M    N KK JJ
1 <NA> -0.5 <NA> 4.5999999999999996 V <NA> <NA> <NA> Yes AA NA NA NA <NA> <NA> NA <NA> NA NA
2 <NA> -0.5 <NA> 4.5999999999999996 V <NA> <NA> <NA> Yes BB NA NA NA <NA> <NA> NA <NA> NA NA
3 <NA> -0.5 <NA> 4.5999999999999996 V <NA> <NA> <NA> Yes CC NA NA NA <NA> <NA> NA <NA> NA NA
4 <NA> -0.5 <NA> 4.5999999999999996 V <NA> <NA> <NA> Yes DD NA NA NA <NA> <NA> NA <NA> NA NA
5 <NA> -0.5 <NA>                2.4 V <NA> <NA> <NA> Yes EE NA NA NA <NA> <NA> NA <NA> NA NA

我不关心数值,但更关心为什么最后几列与我在控制台中使用 print() 看到的不同。

【问题讨论】:

  • 似乎您在4.64.599999... 之间的区别与R FAQ 7.31 有关。但由于它是在您写入文件期间发生的,它可能会受到write.csv 评论的影响:“在几乎所有情况下,数字量的转换都由选项 '"scipen"' 控制(请参阅'options '),但内部等效于 'digits = 15'。为了更好地控制,使用 'format' 来制作字符矩阵/数据框,并在其上调用 'write.table'。".跨度>
  • 数据框中有混合类型。最后两列是数据框本身。这些行被写入最后两列中带有c(NA, NA, NA, NA, NA) 的CSV 文件,因为write.csv 不知道如何处理数据帧。使用save 保存结构并使用load (正确)检索它。
  • @r2evans - 我确实添加了我不关心的问题。我对额外的列以及数据与print(data) 相比有何不同更感兴趣。
  • @EdwardCarney - 我尝试了save(data, file = "data.RData"),然后使用rm(list=ls()) 清理了工作空间。然后使用load("data.RData") 加载,但这没有帮助。在这些操作之后写入文件仍然会导致相同的数据问题。你能详细说明我应该怎么做吗?
  • 这些建议可能有帮助,也可能没有帮助:在使用 fwrite 或 write.csv 之前先创建一个 R 对象 (data.table)。然后我使用 'sapply(DT,class)' 或 sapply(DF,class)' 来检查数据类型。 Rdata.table 将导入列表作为我发现有问题的列表对象。最后,我使用 setnames() 重命名任何标有“T”或“F”的列。我发现标有“T”和“F”的列有问题。我相信我在上面的“T”和“F”列中看到了问题。还要测试 fwrite/write.csv 和 fread/read.delim 之间的差异。

标签: r csv dataframe data.table


【解决方案1】:

您的数据是嵌套的。在这种情况下,它的直接补救措施是微不足道且显而易见的,但如果您的数据在现实中并不完全合作,那么这个答案可能还不够。

这是一个原因:在最后两列中嵌入了帧:

str(dat)
# 'data.frame': 5 obs. of  19 variables:
#  $ A: chr  NA NA NA NA ...
#  $ B: chr  "-0.5" "-0.5" "-0.5" "-0.5" ...
#  $ T: chr  NA NA NA NA ...
#  $ C: chr  "4.5999999999999996" "4.5999999999999996" "4.5999999999999996" "4.5999999999999996" ...
#  $ R: chr  "V" "V" "V" "V" ...
#  $ D: chr  NA NA NA NA ...
#  $ S: chr  NA NA NA NA ...
#  $ E: chr  NA NA NA NA ...
#  $ F: chr  "Yes" "Yes" "Yes" "Yes" ...
#  $ G: chr  "AA" "BB" "CC" "DD" ...
#  $ H: num  NA NA NA NA NA
#  $ I: num  NA NA NA NA NA
#  $ J: num  NA NA NA NA NA
#  $ K: chr [1:5, 1] NA NA NA NA ...
#  $ L: chr [1:5, 1] NA NA NA NA ...
#  $ M: num  NA NA NA NA NA
#  $ N: chr [1:5, 1] NA NA NA NA ...
#  $ O:'data.frame':    5 obs. of  1 variable:       <-----
#   ..$ KK: num  NA NA NA NA NA
#  $ P:'data.frame':    5 obs. of  1 variable:       <-----
#   ..$ JJ: num  NA NA NA NA NA

让我们验证我们的“简单”修复是否足够安全:

islst <- sapply(dat, is.list)
# ASSERT: number of rows and embedded lists/frames are the same length
all(nrow(dat) == sapply(dat[islst], lengths))
# [1] TRUE

这很重要,因为以下操作要么失败(更好),要么在功能上成功但在逻辑上破坏数据而没有警告(糟糕!)。

dat <- do.call("cbind.data.frame", c(dat[!islst], dat[islst], stringsAsFactors = FALSE))
str(dat)
# 'data.frame': 5 obs. of  19 variables:
#  $ A : chr  NA NA NA NA ...
#  $ B : chr  "-0.5" "-0.5" "-0.5" "-0.5" ...
#  $ T : chr  NA NA NA NA ...
#  $ C : chr  "4.5999999999999996" "4.5999999999999996" "4.5999999999999996" "4.5999999999999996" ...
#  $ R : chr  "V" "V" "V" "V" ...
#  $ D : chr  NA NA NA NA ...
#  $ S : chr  NA NA NA NA ...
#  $ E : chr  NA NA NA NA ...
#  $ F : chr  "Yes" "Yes" "Yes" "Yes" ...
#  $ G : chr  "AA" "BB" "CC" "DD" ...
#  $ H : num  NA NA NA NA NA
#  $ I : num  NA NA NA NA NA
#  $ J : num  NA NA NA NA NA
#  $ K : chr  NA NA NA NA ...
#  $ L : chr  NA NA NA NA ...
#  $ M : num  NA NA NA NA NA
#  $ N : chr  NA NA NA NA ...
#  $ KK: num  NA NA NA NA NA
#  $ JJ: num  NA NA NA NA NA

从这里您可以使用write.csv 并编写正确的 CSV 文件。

请注意,您在此处丢失了 P 列名,取而代之的是 KKJJ(嵌套的列名)。如果保留 P 名称很重要,则改为执行此操作(使用未修改的原始 dat):

dat[islst] <- Map(function(x, onm, inm) `names<-`(x, paste(onm, inm, sep = ".")),
                  dat[islst], names(dat[islst]), sapply(dat[islst], names))
dat <- do.call("cbind.data.frame", c(dat[!islst], dat[islst], stringsAsFactors = FALSE))
str(dat)
# 'data.frame': 5 obs. of  19 variables:
#  $ A   : chr  NA NA NA NA ...
#  $ B   : chr  "-0.5" "-0.5" "-0.5" "-0.5" ...
#  $ T   : chr  NA NA NA NA ...
#  $ C   : chr  "4.5999999999999996" "4.5999999999999996" "4.5999999999999996" "4.5999999999999996" ...
#  $ R   : chr  "V" "V" "V" "V" ...
#  $ D   : chr  NA NA NA NA ...
#  $ S   : chr  NA NA NA NA ...
#  $ E   : chr  NA NA NA NA ...
#  $ F   : chr  "Yes" "Yes" "Yes" "Yes" ...
#  $ G   : chr  "AA" "BB" "CC" "DD" ...
#  $ H   : num  NA NA NA NA NA
#  $ I   : num  NA NA NA NA NA
#  $ J   : num  NA NA NA NA NA
#  $ K   : chr  NA NA NA NA ...
#  $ L   : chr  NA NA NA NA ...
#  $ M   : num  NA NA NA NA NA
#  $ N   : chr  NA NA NA NA ...
#  $ O.KK: num  NA NA NA NA NA
#  $ P.JJ: num  NA NA NA NA NA

顺便说一句:这里肯定还有其他选择可以通过代码高尔夫获胜:

dat$P <- dat$P$JJ
dat$O <- dat$O$KK

但如果您在OP 中有可变数量的列,它就会变成一个手动过程。我上面提供的解决方案更加程序化和动态化。


旁注:我将此处使用的变量重命名为dat,因为data(和许多其他变量名称)是基本R函数的名称;当变量被这样命名时,故障排除是复杂的(特别是如果你不知道“闭包”是什么),即当你忘记加载所有变量并期望事情能够正常工作时。例如,您更清楚哪个错误?

# oops, I did not load my 'data' frame
summary(data)
# Error in object[[i]] : object of type 'closure' is not subsettable

# oops, I did not load my 'x' frame
summary(x)
# Error in summary(x) : object 'x' not found

【讨论】:

  • 这个答案能解决你的问题吗?如果没有,你能说什么不起作用吗? (如果是,请接受。)
猜你喜欢
  • 2015-11-10
  • 2019-09-20
  • 2020-08-25
  • 1970-01-01
  • 1970-01-01
  • 2015-11-30
  • 2017-09-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多