首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >dbplyr选择不重复列

dbplyr选择不重复列
EN

Stack Overflow用户
提问于 2021-12-11 06:40:03
回答 1查看 213关注 0票数 -1

我正在使用R编程语言。我有一个位于服务器上的下表:

代码语言:javascript
复制
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

我的目标是从上面的表中删除相同的列,即使它们有不同的名称。因此,最终产品将如下所示:

代码语言:javascript
复制
  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

我的问题:,我想直接从服务器上的表中删除这些重复的列。我一直在阅读R中的"dbplyr“库,我不确定它是否能够做到这一点。我尝试了以下两种方法:

方法1:

代码语言:javascript
复制
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 %>%
                           `!`))

方法2:

代码语言:javascript
复制
mtcars2 <- tbl(con, "testframe")


final_2 = mtcars2 %>%
    dplyr::select(., which(as.list(.) %>%
                               duplicated %>%
                               `!`))

在上面的示例中,数据("testframe")位于我的本地环境中,但我尝试使用copy_con语句,以查看如果数据位于服务器上,这些语句是否有效。

我的问题:上述示例中的代码似乎有效--但我不确定上面的代码是否只能对本地环境中的数据执行这些语句--或者它也可以对位于服务器上的数据执行这些相同的语句。有人能对此发表意见吗?

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-12 20:21:32

dbplyr通过将dplyr命令转换为相应的数据库语言来工作,然后将这些命令传递给数据库。我强烈怀疑它很难翻译which(as.list(.) %>% duplicated %>% '!'),因为你要求它翻译这些指令的意思,而不是直译命令。

可以使用模拟数据库连接测试dbplyr转换。例如:

代码语言:javascript
复制
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就无法将您的指令转换成数据库语言。

对于这类问题,我可能会采取如下方法:

代码语言:javascript
复制
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命令检查每个值是否相等。如果相等值的数目等于值的总数,则将该列匹配为重复。然后,可以使用输出来选择非重复列。

备注

  • !!sym(colA)将存储在变量colA中的文本转换为dbplyr的列名,dbplyr handle.
  • collect()是将数据从数据库中提取到本地R内存的命令。只有当您确信数据将适合本地内存时才会这样做。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70313117

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档