我正在使用 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
我的目標是從上述表格中洗掉相同的列,即使它們具有不同的名稱。因此,最終產品將如下所示:
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”庫,我不確定這是否能夠做到這一點。我嘗試了以下兩種方法:
方法一:
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陳述句來嘗試查看如果資料位于服務器上,這些陳述句是否有效。
我的問題:上述示例中的代碼似乎有效 - 但我不確定上面的代碼是否只能對本地環境中的資料執行這些陳述句 - 或者它也可以對位于服務器上的資料執行這些相同的陳述句。有人可以對此發表評論嗎?
謝謝!
uj5u.com熱心網友回復:
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 命令檢查每個值是否相等。如果相等值的數量等于值的總數,則將該列作為重復項進行匹配。然后,您可以使用輸出來選擇非重復列。
筆記
!!sym(colA)獲取存盤在該變數中的文本colA并將其轉換為 dbplyr 可以處理的列名。collect()是從資料庫中拉取資料到本地R記憶體的命令。只有在您確信資料適合本地記憶體時才執行此操作。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/380086.html
