有没有一种有效的方法可以附加到现有的 csv 文件而不在 R 中重复?

Posted

技术标签:

【中文标题】有没有一种有效的方法可以附加到现有的 csv 文件而不在 R 中重复?【英文标题】:Is there an efficient way to append to an existing csv file without duplicates in R? 【发布时间】:2015-03-14 05:34:05 【问题描述】:

有一个 data.frame 附加到现有文件。当它被 write.table 函数附加时,它可能会导致重复记录到文件中。下面是示例代码:

df1<-data.frame(name=c('a','b','c'), a=c(1,2,2))
write.csv(df1, "export.csv", row.names=FALSE, na="NA"); 

#"export.csv" keeps two copies of df1
write.table(df1,"export.csv", row.names=F,na="NA",append=T, quote= FALSE, sep=",", col.names=F);

所以理想情况下,输出文件应该只保留一份 df1 的副本。但是write.table函数没有任何重复检查的参数。

提前感谢您的任何建议。

【问题讨论】:

使用 rbind 在 R 会话中追加并在写入 CSV 之前删除重复项? @AnandaMahto 对不起,我的示例具有误导性。前两个命令创建测试文件。在我的真实代码中,如果没有预先读取 df1,它就不会在内存中。 您始终可以在 R 之外执行此操作。附加所有文件,然后使用 csvkit 之类的东西来处理 CSV。 【参考方案1】:
> # Original Setup ----------------------------------------------------------
> df1 <- data.frame(name = c('a','b','c'), a = c(1,2,2))
> write.csv(df1, "export.csv", row.names=FALSE, na="NA"); 
> 
> # Add Some Data -----------------------------------------------------------
> df1[,1]  <- as.character(df1[,1])
> df1[,2]  <- as.numeric(df1[,2])
> df1[4,1] <- 'd'
> df1[4,2] <- 3
> 
> # Have a Look at It -------------------------------------------------------
> head(df1)
  name a
1    a 1
2    b 2
3    c 2
4    d 3
> 
> # Write It Out Without Duplication ----------------------------------------
> write.table(df1, "export.csv", row.names=F, na="NA", 
+             append = F, quote= FALSE, sep = ",", col.names = T)
> 
> # Proof It Works ----------------------------------------------------------
> proof <- read.csv("export.csv")
> head(proof)
  name a
1    a 1
2    b 2
3    c 2
4    d 3

您可以交替关注建议rbind 的问题评论,或简单地使用write.csvwrite.tableappend = T 选项,确保正确处理行名和列名。

但是,我也建议使用 readRDSsaveRDS 并仅覆盖 rds 对象,而不是作为最佳实践追加。 Hadley 和 R 中的其他***名称推荐使用 RDS

【讨论】:

【参考方案2】:

您可以使用新的 data.frame 从文件 rbind 中读取 data.frame 并检查重复值。为了编写效率,只追加非重复行。

如果您提出这个问题是因为您正在处理大数据集并且担心读/写时间,请查看data.tablefread 包。

# initial data.frame
df1<-data.frame(name=c('a','b','c'), a=c(1,2,2))
write.csv(df1, "export.csv", row.names=FALSE, na="NA")

# a new data.frame with a couple of duplicate rows
df2<-data.frame(name=c('a','b','c'), a=c(1,2,3))
dfRead<-read.csv("export.csv") # read the file
all<-rbind(dfRead, df2) # rbind both data.frames
# get only the non duplicate rows from the new data.frame
nonDuplicate <- all[!duplicated(all)&c(rep(FALSE, dim(dfRead)[1]), rep(TRUE, dim(df2)[1])), ]
# append the file with the non duplicate rows
write.table(nonDuplicate,"export.csv", row.names=F,na="NA",append=T, quote= FALSE, sep=",", col.names=F)

【讨论】:

感谢您的建议。有什么办法可以避免读取现有文件? @YYY 是的。您可以在不导入或导出文件的情况下使用rbind。它适用于任何两个具有相同列数的 R 对象。 对不起我的样本误导。前两个命令创建测试文件。在我的真实代码中,如果没有预先读取 df1,它就不会在内存中。 @YYY 哦,我明白了。所以你想在不读入的情况下将新数据写入 csv?是的,你也可以这样做。 @Sirvydas 是的。如何在不阅读但不重复检查的情况下做到这一点。

以上是关于有没有一种有效的方法可以附加到现有的 csv 文件而不在 R 中重复?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 fast-csv npm 将新行或新行的数据(新行)附加到现有的 csv 文件

无法将熊猫数据框附加到现有的 Excel 工作表

如何将熊猫数据添加到现有的 csv 文件中?

如何附加到现有的 java.io.ObjectStream? [复制]

附加到现有的json文件

使用 Groovy 将 json 附加到现有的 json 文件中