Oracle 在 R 中创建影子或不可见列

ROracle creates shadow or invisble columns in R

使用通过 ROracle 读入 Rstudio 服务器的 data.frame,我遇到了一些非常奇怪的行为。数据中似乎有一个额外的列,R 起初似乎没有检测到,但仍然非常多。

之前不知道oracle hidden fields,偶然发现了这个,可以解释这个现象。 What are Oracle hidden fields?

然而,这对我来说仍然非常奇怪,这在 R 中甚至是可能的,而且不一致令人困惑。当然,该示例不可重现,因为它基于特定的 oracle 数据集,该数据集已使用 dbReadTable 成功加载到 R 中。我只想向使用 ROracle 的任何人强调这一点,这是你可以进入 Rstudio 的内容,以及当隐藏列加载到 R 中时从 Rstudio 的角度来看它的样子。

有人可以解释一下 $ 运算符和 [[]] 或 exists() 之间的内在区别是什么,以及为什么 $ 运算符似乎是检测此列的唯一方法

> EXAMPLE_TABLE <-
+   dbReadTable(
+     con_ROracle,
+     schema  = SCHEMA_NR,
+     name  = TABLE_NAME) %>%
+   head(100)
> 
> # names doesn't find the column
> 
> "L" %in% names(EXAMPLE_TABLE)
[1] FALSE
> 
> # subsetting with [["L"]] doesn't find it
> EXAMPLE_TABLE[["L"]]
NULL
> 
> # the function "exists" doesn't find it
> 
> exists("L", EXAMPLE_TABLE)
[1] FALSE
> 
> # dplyr selection doesn't find it
> 
> EXAMPLE_TABLE %>% 
+   select(L)
Error: Can't subset columns that don't exist.
x The column `L` doesn't exist.
Run `rlang::last_error()` to see where the error occurred.
> 
> # But the $ operator does find it!
> EXAMPLE_TABLE$L 
  [1]  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1
 [53]  1  1  1  1  1  1  1  1 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
> 
> # And  replacing it with a NULL value doesn't work 
> 
> EXAMPLE_TABLE$L <- NULL
> EXAMPLE_TABLE$L 
  [1]  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1
 [53]  1  1  1  1  1  1  1  1 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
> 
> # The values of the hidden field are accesible 
> new_value <- EXAMPLE_TABLE$L
> new_value
  [1]  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1
 [53]  1  1  1  1  1  1  1  1 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
> 
> 
> # Only replacing with new values helps
> 
> EXAMPLE_TABLE$L <- 5
> EXAMPLE_TABLE$L
  [1] 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
 [79] 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5

>

奇怪的是,隐藏列不能用<-NULL删除,但可以用它覆盖。

当使用 $ 到 select 列时,它不需要完全匹配。您必须有一个名称以 L 开头的列,并且这是唯一以 L 开头的列。

查看 mtcars 的示例

 colnames(mtcars)
 # both return the column corresponding to mpg
 mtcars$mpg
 mtcars$m