本文介绍了通过sqlQuery()删除重复的列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用R编程语言。假设我有以下数据框:

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

如果要删除名称不同但值相同的列,可以使用以下代码行:

no_dup = testframe[!duplicated(as.list(testframe))]

 head(no_dup)
  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

我的问题:假设数据框不在全局环境中-是否可以通过sqlQuery()命令传递上述代码行?例如:

library(RODBC)
library(sqldf)

con = odbcConnect("some name", uid = "some id", pwd = "abc")

#not sure if this is correct?
sample_query = sqlQuery(con, "testframe[!duplicated(as.list(testframe))]")

有人能教我怎么做吗?

谢谢!

推荐答案

这将执行在SQL端的所有实质性处理,并且只在R端执行名称操作。数据库未下载到%r。

第一个管道输入名称(我们已将名称硬编码在名称中,但如果需要,您可以从数据库中检索它们)并返回一条SQL语句,当对数据库运行该语句时,它将从数据库中生成一行数据框,该数据框具有针对测试框中的每对变量的列,其值是不相等的值的数目。

然后我们使用sqldf运行sql1以获得重现性,但您可以将其替换为对sqlQuery的适当调用。

然后,第二个管道使用numDF在字符向量sql2中生成一个或多个SQL语句,以删除重复的列,也就是那些没有不相等值的列,然后您可以对数据库运行这些SQL语句。

我们将SQLdf与SQLite一起使用是为了实现重现性,但您可以使用适当修改后的sqlQuery调用来替换对sqldf的调用,例如,sqlQuery(con,sql1),其中con是您先前定义的连接。

您正在使用的任何数据库系统都可能接受相同的SQL,但如果不是这样,则可能需要在代码中进行一些小的更改,以生成您正在使用的任何数据库系统都接受的SQL。

library(magrittr)
library(sqldf)

Names <- c("age", "height", "height2", "gender", "gender2")

sql1 <- Names %>%
  { toString(sprintf("sum(%s)", combn(., 2, paste, collapse = "!="))) } %>%
  paste("select", ., "from testframe")

numDF <- sqldf(sq11)  # replace with call to your database

sql2 <- numDF %>%
  Filter(Negate(c), .) %>%
  names %>%
  sub(".*!=(.*.).", "alter table testframe drop \1", .)

# Just run the sql2 part against your db, not select * ... part.
# The select * ... downloads table for demo purposes only.
sqldf(c(sql2, "select * from testframe"))  # replace 
##    age height gender
## 1   18   76.1      M
## 2   19   77.0      F
## 3   20   78.1      M
## 4   21   78.2      M
## ...snip...

请注意,以下是SQL1和SQL2。SQL1是单个SQL SELECT语句,而SQL2是SQL ALTER语句的一个向量,每一列要删除一条语句。如果您的数据库允许ALTER一次删除多列,则可以简化此操作,但SQLite一次只允许删除一列。

sql1
## [1] "select sum(age!=height), sum(age!=height2), sum(age!=gender), sum(age!=gender2), sum(height!=height2), sum(height!=gender), sum(height!=gender2), sum(height2!=gender), sum(height2!=gender2), sum(gender!=gender2) from testframe"

sql2
## [1] "alter table testframe drop height2" "alter table testframe drop gender2"

这篇关于通过sqlQuery()删除重复的列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-03 00:24