在 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;
您可以使用 aggregate
和 paste
:
在 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
所以程序代码变量其实本身就是一个列表。如果这是一个问题,您可以将 paste
与 collapse =", "
参数一起使用,使其 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分组=](toString
是 paste(., 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)
我正在尝试创建审计报告,该报告获取通话记录数据 [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;
您可以使用 aggregate
和 paste
:
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
所以程序代码变量其实本身就是一个列表。如果这是一个问题,您可以将 paste
与 collapse =", "
参数一起使用,使其 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分组=](toString
是 paste(., 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)