【问题标题】:unique identifier in data.tabledata.table 中的唯一标识符
【发布时间】:2013-04-16 19:11:26
【问题描述】:

我有一个data.table,其中包含 11 个变量和 200,000 多行。我试图在这个data.table 中找到unique identifier(换句话说,key)。

我在 Stata 中寻找类似 @​​987654321@ 的东西,它检查指定的变量是否唯一地标识了观察结果。有人可以帮忙吗?

【问题讨论】:

  • 行名在数据帧中必须是唯一的。关于 Stata 中的 isid 属性,您还没有告诉我们更多信息。您还需要澄清您是在使用贡献的 data.table 包,还是仅仅对 data.frame 的正确术语感到困惑。
  • @DWin - 我没有混淆 data.frame 和 data.table。我正在使用包 data.table。我希望有 R 和 Stata 知识的人来回答这个问题。但由于您似乎不熟悉 Stata,isid var1 var2 检查 var1 和 var2 是否构成数据集中的键。我正在 R 中寻找类似的东西。给定一个包含很多变量的数据集,我只想断言关键是我认为的。
  • @Arun 没有帮助。不过谢谢!
  • @user2012406,在这种情况下,执行:all(key(DT) %in% c("var1", "var2")
  • 我相信您对 data.table-objects 中的“键”是唯一标识符感到困惑。

标签: r uniqueidentifier data.table stata


【解决方案1】:

这并不能完全回答 OP 的问题 [我还没有使用过 data.table],但它将帮助 R 只有用户回答 OP 的问题。我的重点是解释isid 是如何实际处理Stata 的。我使用来自R 数据库的数据(您需要为此数据安装optmatch)。

library(optmatch)
data(nuclearplants)
sample<-nuclearplants

我只关注数据框的子集,因为我的目标是只解释isid 在做什么:

sample<-sample[,c(1,2,5,10)]
head(sample,5)
 cost  date  cap cum.n
H 460.05 68.58  687    14
I 452.99 67.33 1065     1
A 443.22 67.33 1065     1
J 652.32 68.00 1065    12
B 642.23 68.00 1065    12

现在,当我使用Stata 命令isid cost 时,它不显示任何内容,这意味着没有重复的成本观察结果(R 命令是unique(sample$cost)sample[duplicated(sample),]

[1] cost  date  cap   cum.n
<0 rows> (or 0-length row.names).)

但是,当我们使用 isid date 即日期变量时,Stata 报告它不是唯一的。或者,如果您运行duplicates date examplesStata 会给您重复的观察结果,如下所示:

. duplicates example date

Duplicates in terms of date

  +-------------------------------+
  | group:   #   e.g. obs    date |
  |-------------------------------|
  |      1   2         27   67.25 |
  |      2   2          2   67.33 |
  |      3   3         29   67.83 |
  |      4   2          4      68 |
  |      5   5          8   68.42 |
  |-------------------------------|
  |      6   2          1   68.58 |
  |      7   2         12   68.75 |
  |      8   3         14   68.92 |
  +-------------------------------+

为了解释输出,表示观察 67.25 有两个重复观察(如 # 所示)。第一个观察对应于第 27 行(它没有用 67.25 标识第二个重复的行号)。 Group 为每次重复提供唯一标识符。

R command for the same is duplicated(sample$date). 
duplicated(sample$date)
 [1] FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE  TRUE FALSE  TRUE FALSE  TRUE  TRUE
[22] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE

To identify the unique observation we can also use unique(sample$date) in R. 

我们可以对两个变量 isid cost date 做同样的事情。同样,Stata 不能识别跨两个变量的重复观察。在R 中使用unique(sample[,c(1,2)] 时也是如此。

如果我在所有四个变量上运行isid,那么Stata 表示它是唯一的(没有警告)。

duplicates example  cost date cap cum_n

Duplicates in terms of cost date cap cum_n

(0 observations are duplicates)

R 中的unique(sample) 也是如此。

结论:因此,我认为只要一个变量是唯一的(即它没有重复的观察值),包含唯一变量的变量组合应该始终是唯一的。如果我错了,请纠正我。

【讨论】:

  • user1493368 给出了isid 的详细示例。请注意,isid 并不是真正的基础。这是一个方便的命令。可以转到bysort cost : assert _N == 1,然后会出现无声同意(返回代码_rc 为0)或bysort date: assert _N == 1,会出现错误消息(返回代码为9)。
【解决方案2】:

我认为您对data.tables 和keys 的几点感到困惑。

  • 除非您明确设置,否则data.table 将没有密钥。
  • data.table不一定必须是唯一的。

您可以编写一个函数来检查某些列是否可以为数据集创建唯一标识符。

我在这里使用了 data.table,并注意在 data.table 的无密钥副本上使用 unique

不是高效的。

 isid <- function(columns, data, verbose  = TRUE){
      if(!is.data.table(data)){
        copyd <- data.table(data)
      } else{ 
      copyd <- copy(data)
      }
     if(haskey(copyd)){
       setkey(copyd, NULL)
     }
    # NA values don't work in keys for data.tables
    any.NA <- Filter(columns, f= function(x) any(is.na(copyd[[x]])))
    if(verbose){
      for(aa in seq_along(any.NA)){message(sprintf('Column %s contains NA values', any.NA[aa] ))}
    }
    validCols <- setdiff(columns, any.NA)
    # cycle through columns 1 at a time
    ncol <- 1L
    validKey <- FALSE
    while(!isTRUE(validKey) && ncol <= length(validCols)){
      anyValid <- combn(x = validCols, m = ncol, FUN = function(xn){
        subd <- copyd[, ..xn]
        result <- nrow(subd) == nrow(unique(subd))
        list(cols = xn, valid = result)
      }, simplify = FALSE)

      whichValid <- sapply(anyValid, `[[`, 'valid')
      validKey <- any(whichValid)
      ncol <- ncol + 1L
    }

 if(!validKey){
 warning('No combinations are unique')
 return(NULL)} else {
   valid.combinations <- lapply(anyValid, `[[`, 'cols')[whichValid]
   if(length(valid.combinations) > 1){
    warning('More than one combination valid, returning the first only')
    }
    return(valid.combinations[[1]])
   }
 }

一些使用中的例子

 oneU <- data.table(a = c(2,1,2,2), b = c(1,2,3,4))
 twoU  <- data.table(a = 1:4, b = letters[1:4])
 bothU <- data.table(a = letters[1:2], b = rep(letters[1:2], each = 2))
 someNA <- data.table(a = c(1,2,3,NA), b = 1:4)

isid(names(oneU), oneU)
# [1] "b"
isid(names(twoU), twoU)
# [1] "a"
# Warning message:
# In isid(names(twoU), twoU) :
#   More than one combination valid, returning the first only
isid(names(bothU), bothU)
# [1] "a" "b"
isid(names(someNA), someNA)
# Column a contains NA values
# [1] "b"

# examples with no valid identifiers

isid('a', someNA)
## Column a contains NA values
## NULL
## Warning message:
## In isid("a", someNA) : No combinations are unique
isid('a', oneU)
## NULL
## Warning message:
##  In isid("a", oneU) : No combinations are unique

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-17
    • 2012-07-18
    • 1970-01-01
    • 2014-03-05
    • 2012-06-02
    • 2012-11-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多