在 R 中连接(相当于使用 sqldf 时的 COALESCE)

Concatenate in R (equivalent of COALESCE when using sqldf)

我正在尝试创建审计报告,该报告获取通话记录数据 [Table 1] 并将其与时间表数据 [Table 2] 进行比较。如果存在与时间表数据 [Table 2].

匹配的呼叫日志数据 [Table 1] 的记录,我需要对 return 'OK' 进行简单查询

Table 1

Date            Project Code    Amount  Employee
11/2/15         30018           250     Tom Thompson
11/2/15         30018           500     John Johnson
11/2/15         20018           500     Jane Doe

Table 2

Project Code    Project Name    Employee       Hours    Dates
30012           A               Jane Doe       4        11/2/15
3200            B               Jane Doe       2        11/2/15
4               C               Jane Doe       1        11/2/15
20018           D               Jane Doe       1        11/2/15
4               C               John Johnson   6        11/2/15

我在 R 中使用 sqldf 包,运行 如下:

test2 = sqldf("
    SELECT a.*,
    CASE
        WHEN
            a.Name = b.employee and a.Date=b.Dates AND
            a.Project like b.ProjectCode
        THEN 'Okay'
        ELSE 'Flag'
        END 'Audit'

    FROM Table_1 as a, Table_2 as b
    WHERE a.Name = b.employee
    GROUP BY a.Name
")

这不是 return 我需要的。维护 SQL 逻辑我想连接 Table 2(或分组依据)以产生:

Project Code            Employee    Dates
30012, 3200, 4, 20018   Jane Doe    11/2/15

我的想法是,我可以在上面的 case 语句中使用 "like" 语句,它会起作用。

您可以使用 EXISTS 子查询轻松完成此操作:

SELECT a.*,
       (CASE WHEN EXISTS (SELECT 1 FROM table_2 b WHERE a.Name = b.employee)
             THEN 'Okay'
             ELSE 'Flag'
        END) as Audit
FROM Table_1 a;

您可以使用 aggregatepaste:

在 base R 中实现所需的输出
aggregate(Project_Code ~ Employee + Dates, data=df, paste, sep=",")
      Employee   Dates          Project_Code
1     Jane_Doe 11/2/15 30012, 3200, 4, 20018
2 John_Johnson 11/2/15                     4

还有一些其他函数会 return 这个结果。正如@nicola 提到的,您也可以使用 toString 来实现这一点。另一种选择是 c.

aggregate(Project_Code ~ Employee + Dates, data=df, c)

看起来就是上面的结果。


但是请注意,此数据的结构比最初出现的要复杂。这是在 c:

的输出上使用 str 的结果

'data.frame': 2 obs. of 3 variables:
$ Employee : Factor w/ 2 levels "Jane_Doe","John_Johnson": 1 2
$ Dates : Factor w/ 1 level "11/2/15": 1 1
$ Project_Code:List of 2
..$ 1.1: int 30012 3200 4 20018
..$ 1.2: int 4

所以程序代码变量其实本身就是一个列表。如果这是一个问题,您可以将 pastecollapse =", " 参数一起使用,使其 return 成为一个字符串变量,看起来或多或少相同:

aggregate(Project_Code ~ Employee + Dates, data=df, paste, collapse=", ")
      Employee   Dates          Project_Code
1     Jane_Doe 11/2/15 30012, 3200, 4, 20018
2 John_Johnson 11/2/15                     4

但结构更简单。

数据

df <- read.table(header=T, text="Project_Code  Project_Name    Employee    Hours    Dates
30012           A               Jane_Doe       4        11/2/15
3200            B               Jane_Doe       2        11/2/15
4               C               Jane_Doe       1        11/2/15
20018           D               Jane_Doe       1        11/2/15
4               C               John_Johnson   6        11/2/15")

使用R,我们可以在两个数据集之间做一个left_join,然后按'Employee'、'Dates'、paste和[=26分组=](toStringpaste(., collapse=', ') 的包装器)

library(dplyr)
left_join(Table_2, Table_1, by = c("ProjectCode", "Dates" = "Date", "Employee")) %>% 
    group_by(Employee, Dates) %>%
    summarise(ProjectCode = toString(ProjectCode))
 #     Employee   Dates           ProjectCode
 #        <chr>   <chr>                 <chr>
 #1     Jane Doe 11/2/15 30012, 3200, 4, 20018
 #2 John Johnson 11/2/15                     4

如@nicola 所述,我们仅使用 'Table_2' 即可获得输出

 Table_2 %>%
      group_by(Employee, Dates) %>%
      summarise(ProjectCode = toString(ProjectCode)) 
 #    Employee   Dates           ProjectCode
 #        <chr>   <chr>                 <chr>
 #1     Jane Doe 11/2/15 30012, 3200, 4, 20018
 #2 John Johnson 11/2/15                     4

数据

 Table_1 <- structure(list(Date = c("11/2/15", "11/2/15", "11/2/15"), 
 ProjectCode = c(30018L, 
 30018L, 20018L), Amount = c(250L, 500L, 500L), Employee = c("Tom Thompson", 
 "John Johnson", "Jane Doe")), .Names = c("Date", "ProjectCode", 
 "Amount", "Employee"), class = "data.frame", row.names = c(NA, -3L))

 Table_2 <- structure(list(ProjectCode = c(30012L, 3200L, 4L, 20018L, 4L), 
ProjectName = c("A", "B", "C", "D", "C"), Employee = c("Jane Doe", 
"Jane Doe", "Jane Doe", "Jane Doe", "John Johnson"), Hours = c(4L, 
2L, 1L, 1L, 6L), Dates = c("11/2/15", "11/2/15", "11/2/15", 
"11/2/15", "11/2/15")), .Names = c("ProjectCode", "ProjectName", 
"Employee", "Hours", "Dates"), class = "data.frame",
 row.names = c(NA, -5L))

问题中的描述、输入、输出和代码都不一致(例如,代码指的是名称输入和审计输出列,但都没有出现在显示的输入和输出中)所以我们假定注释中的输入最后,问题输出中显示的列并修改了代码以解决不一致问题并使用 group_concat

代码可能存在其他问题,但需要更多地说明解决这些问题的意图,特别是关于审计列是否应该被计算,即使没有出现在样本输出中,如果是的话,它究竟代表什么以及主题中对 coalesce 的引用指的是什么。

library(sqldf)

sqldf("SELECT group_concat(b.ProjectCode) as 'Project Code', a.Name, b.Dates
              FROM Table_1 as a
              JOIN Table_2 as b ON a.Name = b.employee
              GROUP BY a.Name")

给予:

                 Project Code         Name   Dates
1          4,3200,20018,30012     Jane_Doe 11/2/15
2                           4 John_Johnson 11/2/15

注意:这些输入是假定的:

Lines1 <- "Date            Project    Amount  Name
11/2/15         30018           250     Tom_Thompson
11/2/15         30018           500     John_Johnson
11/2/15         20018           500     Jane_Doe"

Lines2 <- "ProjectCode    Name    Employee       Hours    Dates
30012           A               Jane_Doe       4        11/2/15
3200            B               Jane_Doe       2        11/2/15
4               C               Jane_Doe       1        11/2/15
20018           D               Jane_Doe       1        11/2/15
4               C               John_Johnson   6        11/2/15"

Table_1 <- read.table(text = Lines1, header = TRUE)
Table_2 <- read.table(text = Lines2, header = TRUE)