到目前为止,我们所教授的是,要找到主键,就需要找到列/变量的组合,每个列/变量的值只匹配一个观察结果。因此,主键中没有一个观测与数据集中的多个观察相匹配。
假设您找到由A、W、X、Y、Z列组成的主键,因为当您按它们分组时,数据集中的每一行都是唯一的。
但结果是,你可以把A,W,X和Z分组。
下面说明了我的问题,这两个列组都产生了不同的值,但事实证明,我不需要包括工资。
Lahman::Salaries %>% count(playerID, yearID, salary, teamID) %>% filter(n>1)
A tibble: 0 x 5
… with 5 variables: playerID <chr>, yearID <int>, salary <int>, teamID <fct>,
n <int>
Lahman::Salaries %>% count(playerID, yearID, teamID) %>% filter(n>1)
A tibble: 0 x 4
… with 4 variables: playerID <chr>, yearID <int>, teamID <fct>, n <int>
在进行检查时,如何知道哪些列是不需要的,以检查下一列(包括时)是否为您提供了主键?
发布于 2020-06-04 17:35:48
这里有一个函数,它不以有效处理大数据为借口。
#' @param x 'data.frame'
#' @param max.columns 'integer', the max number of columns to consider
#' for a key; with most data, this might be at most 'ncol(x)-1'
#' (assuming that there is some numeric or "data" field)
#' @param find 'integer', how many column combinations to look for; if
#' 1 (default), then the first combination is returned, no others
#' attempted; if below 1, all combinations (up through
#' 'max.columns') are considered
#' @param digits 'integer', how to deal with 'numeric' non-'integer'
#' columns; if 'NA' (default), do not consider said columns; if a
#' non-negative integer, the number of digits to round the columns
#' and factorize; note: setting this too low may "find" keys in
#' non-trivial-precision floating-point numbers
#' @return 'list' of 'character', combinations of columns that unique
#' identify the rows given
findkeys <- function(x, max.columns = ncol(x) - 1L, find = 1L, digits = NA) {
isnum <- sapply(x, function(z) is.numeric(z) & !is.integer(z))
force(max.columns)
if (is.na(digits) || digits < 0) {
x <- x[, !isnum, drop = FALSE ]
} else {
possfactors <- lapply(x[,isnum], function(z) as.character(z - trunc(z)))
signif_digits <- sapply(possfactors, function(s) max(nchar(gsub("^0\\.?", "", gsub("(0{5,}|9{5,}).*", "", s)))))
remove <- signif_digits[ signif_digits > digits ]
message("#> Removing: ", paste(sQuote(names(remove)), collapse = ","))
x <- x[, setdiff(colnames(x), names(remove)), drop = FALSE]
}
max.columns <- min(c(max.columns, ncol(x)))
keys <- list()
if (max.columns < 1) {
warning("no columns found, no keys")
return(keys)
}
message("#> Columns : ", paste(sQuote(colnames(x)), collapse = ","))
for (i in seq_len(max.columns)) {
combs <- combn(names(x), i)
for (j in seq_len(ncol(combs))) {
uniq <- unique(x[, combs[,j], drop = FALSE ])
if (nrow(x) == nrow(uniq)) {
keys <- c(keys, list(combs[,j]))
if (find > 0 && length(keys) >= find) return(keys)
}
}
}
keys
}
处决:
findkeys(mtcars)
# Warning in findkeys(mtcars) : no columns found, no keys
# list()
findkeys(mtcars, digits=1)
# #> Removing: 'drat','wt','qsec'
# #> Columns : 'mpg','cyl','disp','hp','vs','am','gear','carb'
# list()
findkeys(mtcars, digits=2)
# #> Removing: 'wt'
# #> Columns : 'mpg','cyl','disp','hp','drat','qsec','vs','am','gear','carb'
# [[1]]
# [1] "mpg" "qsec"
findkeys(tibble::rownames_to_column(mtcars))
# #> Columns : 'rowname'
# [[1]]
# [1] "rowname"
findkeys(Lahman::Salaries)
# #> Columns : 'yearID','teamID','lgID','playerID','salary'
# [[1]]
# [1] "yearID" "teamID" "playerID"
findkeys(Lahman::Salaries, find = 0)
# #> Columns : 'yearID','teamID','lgID','playerID','salary'
# [[1]]
# [1] "yearID" "teamID" "playerID"
# [[2]]
# [1] "yearID" "teamID" "lgID" "playerID"
# [[3]]
# [1] "yearID" "teamID" "playerID" "salary"
这当然是不完美的。例如,我非常怀疑我们是否希望使用"salary"
作为Lahman::Salaries
的密钥。
它当然可以变得更聪明,但就启发式而言,这是快速的、可能有缺陷的,而且是好的--目前来说已经足够了。在使用此方法时,您可能会考虑在此步骤之前删除所有已知的浮点数字,并可能将大数据向下采样.知道取样可能会出现假阳性。
https://stackoverflow.com/questions/62199876
复制相似问题