如何在不重复列名的情况下附加 readr::write_excel_csv 数据?

How to append data with readr::write_excel_csv without repeating column names?

readr::write_excel_csv 的帮助文件建议使用以下代码:

write_excel_csv(x, path, na = "NA", append = TRUE,
  col_names = !append, delim = ",", quote_escape = "double")

但是,col_names = !append 会产生错误。

library(readr)
data <- read_csv("col1, col2, col3
a,2,0
b,5,7
c,8,4")

write_excel_csv(data,"data.csv",append = TRUE, col_names=!append)

>Error in !append : invalid argument type

col_names = !append 是有效代码吗?如果不是,它在 write_excel_csv 的帮助文件上下文中是什么意思?

col_names = TRUE 每次都附加列名。我只希望列名第一次出现。

编辑: 起初我以为这段代码解决了问题,但事实并非如此。它适用于 write.table 但不适用于 write_excel 或 write_excel_csv。 using column names when appending data in write.table

#!file.exists() works with write.table but not with write_excel or write_excel_csv

#column names appear
write.table(data, "data.csv", append=TRUE, col.names=!file.exists("data.csv"))

#column names don't appear
write_excel_csv(data,"data1.csv",append=TRUE, col_names=!file.exists("data1.csv"))

如何使用 write_excel_csv 使列名第一次出现但以后不出现?

我已修改您的数据以创建数据框:

data <- data.frame(col1=c('a','b','c'), 
                   col2=c(2,5,8),
                   col3=c(0,7,4))

产生:

  col1 col2 col3
1    a    2    0
2    b    5    7
3    c    8    4

现在,我构建了一个 if else 语句来查看文件是否存在。如果该文件不存在,它将保存一个包含列名的新 CSV 文件。如果文件确实存在,它 运行s write_excel_csv 只是将新值附加到现有列。

if(file.exists("data.csv") == TRUE) {
  # If the file exists, run the append code.
  write_excel_csv(data,"data.csv", append=TRUE)
} else { 
  # If it doesn't exist, save the file with the columns included.
  write_excel_csv(data, "data.csv", append=FALSE)
}

如果您 运行 代码两次,您将在第一次迭代中看到它会保存一个新的 CSV,其中数据框包含 headers 列(假设您已删除"data.csv" 来自您的目录 )。第二次迭代将简单地附加数据框中的值而没有列 headers,生成:

  col1   col2  col3
  <chr> <dbl> <dbl>
1 a         2     0
2 b         5     7
3 c         8     4
4 a         2     0
5 b         5     7
6 c         8     4

我认为 !append 存在范围问题。 R 将在 调用 readr::write_excel_csv 之前尝试评估该语句 ,如果在你的 .GlobalEnv 中没有调用 append 的 object,它将失败。更糟糕的是,如果在您的工作区中碰巧有一个名为 append 的 object,该值将在调用中使用,这几乎肯定不是您想要的。考虑一下:

f = function (a = TRUE, b = !a) cat("'a' is", a, "; 'b' is", b, '\n')
f()
## 'a' is TRUE ; 'b' is FALSE 

f(b = !a)
## Error in cat("'a' is", a, "; 'b' is", b, "\n") : object 'a' not found

a = FALSE
f(b = !a)
## 'a' is TRUE ; 'b' is TRUE 

当您调用一个函数时,R 将首先评估您为该函数的参数提供的所有语句,然后使用相应的值进行调用。另一方面,如果您不提供具有默认值的参数,该值将在函数范围计算。所以当 readr::write_excel_csv() 评估默认值 !append 时,这发生在函数范围内,其中应该定义 append

现在,col_names = !append 的默认值被巧妙地选择为按您预期的方式工作,即在不追加时写入 headers,大概是在写入一个新文件。因此,如果您不理会它,只是将 append 的值设置为有条件的,它就可以顺利运行:

write_excel_csv(data, 'data1.csv', append=file.exists('data1.csv'))
read_csv('data1.csv')

## Parsed with column specification:
## cols(
##   col1 = col_character(),
##   col2 = col_double(),
##   col3 = col_double()
## )
## # A tibble: 3 x 3
##   col1   col2  col3
##   <chr> <dbl> <dbl>
## 1 a         2     0
## 2 b         5     7
## 3 c         8     4

write_excel_csv(data, 'data1.csv', append=file.exists('data1.csv'))
read_csv('data1.csv')

## Parsed with column specification:
## cols(
##   col1 = col_character(),
##   col2 = col_double(),
##   col3 = col_double()
## )
## # A tibble: 6 x 3
##   col1   col2  col3
##   <chr> <dbl> <dbl>
## 1 a         2     0
## 2 b         5     7
## 3 c         8     4
## 4 a         2     0
## 5 b         5     7
## 6 c         8     4