dbplyr select 不重复列
dbplyr select not duplicate columns
我正在使用 R 编程语言。我在服务器上有以下 table:
age=18:29
height=c(76.1,77,78.1,78.2,78.8,79.7,79.9,81.1,81.2,81.8,82.8,83.5)
gender=c("M","F","M","M","F","F","M","M","F","M","F","M")
testframe = data.frame(age=age,height=height,height2=height,gender=gender,gender2=gender)
head(testframe)
age height height2 gender gender2
1 18 76.1 76.1 M M
2 19 77.0 77.0 F F
3 20 78.1 78.1 M M
4 21 78.2 78.2 M M
5 22 78.8 78.8 F F
6 23 79.7 79.7 F F
我的目标是从上面的 table 中删除相同的列,即使它们具有不同的名称。因此,最终产品将如下所示:
age height gender
1 18 76.1 M
2 19 77.0 F
3 20 78.1 M
4 21 78.2 M
5 22 78.8 F
6 23 79.7 F
我的问题: 我想直接从服务器上的 table 中删除这些重复的列。我一直在阅读 R 中的“dbplyr”库,我不确定这是否能够做到这一点。我尝试了以下两种方法:
方法一:
library(RODBC)
library(sqldf)
library(dplyr)
library(dbplyr)
library(odbc)
con = odbcConnect("some name", uid = "some id", pwd = "abc")
con <- DBI::dbConnect(RSQLite::SQLite(), ":memory:")
copy_to(con, testframe)
final_1 = testframe %>%
dplyr::select(., which(as.list(.) %>%
duplicated %>%
`!`))
方法二:
mtcars2 <- tbl(con, "testframe")
final_2 = mtcars2 %>%
dplyr::select(., which(as.list(.) %>%
duplicated %>%
`!`))
在上面的示例中,数据(“testframe”)在我的本地环境中,但我尝试使用 copy_con
语句来尝试查看如果数据在打开时这些语句是否有效服务器。
我的问题:上面示例中的代码似乎有效 - 但我不确定上面的代码是否只能对本地环境中的数据执行这些语句 -或者它也可以对位于服务器上的数据执行这些相同的语句。有人可以对此发表评论吗?
谢谢!
dbplyr 的工作原理是将 dplyr 命令翻译成相应的数据库语言,然后再将这些命令传递给数据库。我强烈怀疑它会很难翻译 which(as.list(.) %>% duplicated %>% '!')
,因为你要求它翻译这些指令的含义,而不是字面命令对命令的翻译。
您可以使用模拟数据库连接测试 dbplyr 翻译。例如:
library(dplyr)
library(dbplyr)
age=18:29
height=c(76.1,77,78.1,78.2,78.8,79.7,79.9,81.1,81.2,81.8,82.8,83.5)
gender=c("M","F","M","M","F","F","M","M","F","M","F","M")
testframe = data.frame(age=age,height=height,height2=height,gender=gender,gender2=gender)
remote_table = tbl_lazy(testframe , con = simulate_mssql()) # the simulation
remote_table %>%
mutate(height3 = height2) %>%
select(height, height2, height3) %>%
show_query()
如果这产生了有效的数据库代码,那么您就知道您的 dplyr 命令正在按预期工作。但是,如果这产生了意外的数据库命令(或 R 命令出现在翻译中),那么 dbplyr 无法将您的指令翻译成数据库语言。
对于这类问题,我可能会采用如下方法:
all_column_names = colnames(remotetable)
num_cols = length(all_column_names)
is_dupe = rep(0, num_cols)
for(ii in 1:(num_cols - 1)){
for(jj in 2:num_cols) {
colA = all_column_names[ii]
colB = all_column_names[jj]
this_check = remotetable %>%
mutate(compare = ifelse(!!sym(colA) == !!sym(colB), 1, 0)) %>%
ungroup() %>%
summarise(num = n(), matches = sum(compare)) %>%
collect()
if(this_check$num == this_check$matches)
is_dupe[jj] = 1
}
}
想法是遍历所有的列对,并使用基本的 dplyr 命令检查每个值是否相等。如果相等值的数量等于值的总数,则将该列作为重复项进行匹配。然后,您可以将输出用于 select 非重复列。
备注
!!sym(colA)
获取存储在变量 colA
中的文本并将其转换为 dbplyr 可以处理的列名。
collect()
是从数据库拉取数据到本地R内存的命令。仅当您确信数据适合本地内存时才执行此操作。
我正在使用 R 编程语言。我在服务器上有以下 table:
age=18:29
height=c(76.1,77,78.1,78.2,78.8,79.7,79.9,81.1,81.2,81.8,82.8,83.5)
gender=c("M","F","M","M","F","F","M","M","F","M","F","M")
testframe = data.frame(age=age,height=height,height2=height,gender=gender,gender2=gender)
head(testframe)
age height height2 gender gender2
1 18 76.1 76.1 M M
2 19 77.0 77.0 F F
3 20 78.1 78.1 M M
4 21 78.2 78.2 M M
5 22 78.8 78.8 F F
6 23 79.7 79.7 F F
我的目标是从上面的 table 中删除相同的列,即使它们具有不同的名称。因此,最终产品将如下所示:
age height gender
1 18 76.1 M
2 19 77.0 F
3 20 78.1 M
4 21 78.2 M
5 22 78.8 F
6 23 79.7 F
我的问题: 我想直接从服务器上的 table 中删除这些重复的列。我一直在阅读 R 中的“dbplyr”库,我不确定这是否能够做到这一点。我尝试了以下两种方法:
方法一:
library(RODBC)
library(sqldf)
library(dplyr)
library(dbplyr)
library(odbc)
con = odbcConnect("some name", uid = "some id", pwd = "abc")
con <- DBI::dbConnect(RSQLite::SQLite(), ":memory:")
copy_to(con, testframe)
final_1 = testframe %>%
dplyr::select(., which(as.list(.) %>%
duplicated %>%
`!`))
方法二:
mtcars2 <- tbl(con, "testframe")
final_2 = mtcars2 %>%
dplyr::select(., which(as.list(.) %>%
duplicated %>%
`!`))
在上面的示例中,数据(“testframe”)在我的本地环境中,但我尝试使用 copy_con
语句来尝试查看如果数据在打开时这些语句是否有效服务器。
我的问题:上面示例中的代码似乎有效 - 但我不确定上面的代码是否只能对本地环境中的数据执行这些语句 -或者它也可以对位于服务器上的数据执行这些相同的语句。有人可以对此发表评论吗?
谢谢!
dbplyr 的工作原理是将 dplyr 命令翻译成相应的数据库语言,然后再将这些命令传递给数据库。我强烈怀疑它会很难翻译 which(as.list(.) %>% duplicated %>% '!')
,因为你要求它翻译这些指令的含义,而不是字面命令对命令的翻译。
您可以使用模拟数据库连接测试 dbplyr 翻译。例如:
library(dplyr)
library(dbplyr)
age=18:29
height=c(76.1,77,78.1,78.2,78.8,79.7,79.9,81.1,81.2,81.8,82.8,83.5)
gender=c("M","F","M","M","F","F","M","M","F","M","F","M")
testframe = data.frame(age=age,height=height,height2=height,gender=gender,gender2=gender)
remote_table = tbl_lazy(testframe , con = simulate_mssql()) # the simulation
remote_table %>%
mutate(height3 = height2) %>%
select(height, height2, height3) %>%
show_query()
如果这产生了有效的数据库代码,那么您就知道您的 dplyr 命令正在按预期工作。但是,如果这产生了意外的数据库命令(或 R 命令出现在翻译中),那么 dbplyr 无法将您的指令翻译成数据库语言。
对于这类问题,我可能会采用如下方法:
all_column_names = colnames(remotetable)
num_cols = length(all_column_names)
is_dupe = rep(0, num_cols)
for(ii in 1:(num_cols - 1)){
for(jj in 2:num_cols) {
colA = all_column_names[ii]
colB = all_column_names[jj]
this_check = remotetable %>%
mutate(compare = ifelse(!!sym(colA) == !!sym(colB), 1, 0)) %>%
ungroup() %>%
summarise(num = n(), matches = sum(compare)) %>%
collect()
if(this_check$num == this_check$matches)
is_dupe[jj] = 1
}
}
想法是遍历所有的列对,并使用基本的 dplyr 命令检查每个值是否相等。如果相等值的数量等于值的总数,则将该列作为重复项进行匹配。然后,您可以将输出用于 select 非重复列。
备注
!!sym(colA)
获取存储在变量colA
中的文本并将其转换为 dbplyr 可以处理的列名。collect()
是从数据库拉取数据到本地R内存的命令。仅当您确信数据适合本地内存时才执行此操作。