格式化粘贴函数的输出以包含缺少值的 NULL

Format the output from paste function to include NULL where values are missing

我有一个包含三列(a、b、c)的数据集。

  a   b  c
  ----------------- 
  63  0        
  78  0        
  79  0        
  10  0        
  11  0        
  12  0        
  13  0       
  16  0        
  16  0        
  16  1  2014-04-24

我正在尝试将这些列中的值插入到来自 R 的 SQL table 中。

我正在使用粘贴函数将数据集中的值传递到 SQL 语句中。

valuestest1 <- paste("(",df$a,",",df$b,",",df$c,")", sep="", collapse=",")
valuestest1

我从这个粘贴函数得到的输出如下:

"(63,0,),(78,0,),(79,0,),(10,0,),(11,0,),(12,0,),(13,0,),(16,0,),(16,0,),(16,1,2014-04-24)"

这不适用于插入语句,因为经过大量的反复试验,我发现:

1) 我需要在缺少值的地方插入 NULL,如下所示:

      "(63,0,NULL),(78,0,NULL),(79,0,NULL),(10,0,NULL),(11,0,NULL),(12,0,NULL),(13,0,NULL),(16,0,NULL),(16,0,NULL),(16,1,2014-04-24)"

2) 我应该用单引号将日期值括起来,如 '2014-04-24'

       "(63,0,NULL),(78,0,NULL),(79,0,NULL),(10,0,NULL),(11,0,NULL),(12,0,NULL),(13,0,NULL),(16,0,NULL),(16,0,NULL),(16,1,'2014-04-24')"

现在,我不知道如何格式化这个粘贴函数来产生这样的输出。

所以我需要帮助。谢谢各位,非常感谢您的宝贵时间。

我们可以 transform 'c' 列中的空白元素,即 '' 到 'NULL'。在这里我使用 ifelse 来做到这一点。我们 paste 行一起使用 do.call(paste,参数可以放在 list (list(sep=',')) 中,通过包含 ( 和 [=22] 来格式化字符串=] 与 sprintfcollapse 将其转换为带有 paste 的单个字符串。我们可以通过将 () 粘贴到外部 paste 来删除 sprintf 步骤。

paste(
    sprintf('(%s)',
         do.call(paste,
              c(transform(df1, c= ifelse(c=='', 'NULL', c)),
                                 list(sep=',')))),
                                          collapse=',')
#[1] "(63,0,NULL),(78,0,NULL),(79,0,NULL),(10,0,NULL),(11,0,NULL),(12,0,NULL),(13,0,NULL),(16,0,NULL),(16,0,NULL),(16,1,2014-04-24)"

如果 '2014-04-24' 需要单引号,我们可以更改 ifelse 语句以使用 sprintf.

格式化 'Date'
 paste(
    sprintf('(%s)',
         do.call(paste,
              c(transform(df1, c= ifelse(c=='', 'NULL', sprintf("'%s'",c))),
                                 list(sep=',')))),
                                          collapse=',')
#[1] "(63,0,NULL),(78,0,NULL),(79,0,NULL),(10,0,NULL),(11,0,NULL),(12,0,NULL),(13,0,NULL),(16,0,NULL),(16,0,NULL),(16,1,'2014-04-24')"

注意:这提供了 OP post 中显示的预期结果。此外,即使有 100 列左右,它也应该工作,即我们不需要手动输入

 paste("(",df$a,",",df$b,",",df$c,...., df$xyz...`

数据

df1 <- structure(list(a = c(63L, 78L, 79L, 10L, 11L, 12L, 13L, 16L, 
16L, 16L), b = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L), c = c("", 
"", "", "", "", "", "", "", "", "2014-04-24")), .Names = c("a", 
"b", "c"), class = "data.frame", row.names = c(NA, -10L))

假设这是您的数据并且格式正确,您将拥有:

df <- data.frame(a = c(63, 78, 79, 10, 11, 12, 13, 16, 16, 16), b=c(0, 0, 0, 0, 0, 0, 0, 0, 0, 1), c=c("","","","","","","","","","2014-04-24"), stringsAsFactors=FALSE)       

> df
    a b          c
1  63 0           
2  78 0           
3  79 0           
4  10 0           
5  11 0           
6  12 0           
7  13 0           
8  16 0           
9  16 0           
10 16 1 2014-04-24

继续,在第 3 列中为所有内容加上引号:

df[,3] <- paste("'", df[, 3], "'", sep="")

...并得到:

> df
    a b            c
1  63 0           ''
2  78 0           ''
3  79 0           ''
4  10 0           ''
5  11 0           ''
6  12 0           ''
7  13 0           ''
8  16 0           ''
9  16 0           ''
10 16 1 '2014-04-24'

现在,处理空引号:

> df[df=="''"]<-'NULL'

这给了你

> df
    a b            c
1  63 0           NULL
2  78 0           NULL
3  79 0           NULL
4  10 0           NULL
5  11 0           NULL
6  12 0           NULL
7  13 0           NULL
8  16 0           NULL
9  16 0           NULL
10 16 1 '2014-04-24'

现在您可以像在问题中那样粘贴:

    valuestest1 <- paste("(",df$a,",",df$b,",",df$c,")", sep="", collapse=",")
    valuestest1
[1] "(63,0,NULL),(78,0,NULL),(79,0,NULL),(10,0,NULL),(11,0,NULL),(12,0,NULL),(13,0,NULL),(16,0,NULL),(16,0,NULL),(16,1,'2014-04-24')"