检查和可视化 gaps/blanks 和大型数据帧中的结构
Inspecting and visualizing gaps/blanks and structure in large dataframes
我有一个大型数据框 (400000 x 50),我想对其结构进行目视检查,blanks/gaps。
有没有现成的库或ggplot2函数,可以吐出这样的图:
红色可能是 "Dates",蓝色可能是 "factors",绿色可能是 "characters",黑色可能是 blanks/NAs。
假设您所说的 blank/gaps 是缺失值 (NA)
image(t(as.matrix(is.na(df))))
您可能想看看 tabplot
包。这么大的 data.frame
加载需要一段时间,但它应该也能正确识别缺失值。更多信息 here。
这是一个使用钻石 data.frame
的图像示例。
编辑
我刚看到你说你的 df 有 50 列。我在那个尺寸的 df 上使用了 tabplot,发现信息的分辨率受屏幕宽度的限制。行数也可能是一个问题,但我个人发现如果 df 太宽,则会丢失更多信息。因此,我建议您将其解析为 3 个单独的 df(例如使用 dplyr
),然后通过 tabplot
或类似的 tableplot()
函数将它们 运行。
您在 lasagnar
中尝试过 dfviewr
吗?下面重现包中 50 行 x 10 列 df.in
所需的图形:
library(devtools)
install_github("swihart/lasagnar")
library(lasagnar)
dfviewr(df=df.in)
## also try:
##dfviewr(df=df.in, legend=FALSE)
##dfviewr(df=df.in, gridlines=FALSE)
所以,公平地说,dfviewr
在提出问题时并不存在,但要了解导致其发展的一些想法以及如何实际可视化 400,000 行,请参阅 for - 在最底部循环,不要太鲁莽 运行 df2.in
(400,000 x 50):
上的函数
## Do not run:
## system.time(dfviewr(df=df2.in, gridlines=FALSE)) ## 10 minutes before useRaster=TRUE
## 2 minutes after
此外,tabplot:::tableplot()
似乎不支持日期或字符:
library(tabplot)
tableplot(df.in)
产生:
Error in ff(initdata = initdata, length = length, levels = levels, ordered = ordered, : vmode 'character' not implemented
所以我们删除字符列 (#9):
tableplot(df.in[,c(-9)])
产生:
Error in UseMethod("as.hi") :
no applicable method for 'as.hi' applied to an object of class "c('POSIXct', 'POSIXt')"
所以我们也删除了第一列(日期):
tableplot(df.in[,c(-1,-9)])
并获得
对于没有日期或字符列的 400,000 x 50 df2.in
,图像渲染速度非常快(6 秒):
system.time(tableplot(df2.in[,c(-(1+seq(0,40,10)), -(9+seq(0,40,10))) ]))
感兴趣的 reader...
我首先展示一个 50 行的婴儿示例,然后是 400,000 行的示例。
对于它的价值,我支持@cmbarbu 的评论,即在同一个绘图上视觉查看 400K 行受到屏幕的限制,该屏幕最多具有 2K 像素的高度,因此可能会出现某种跨页面分离的情况有利于防止重叠。我尝试通过在 1000 plots/pages 中制作一个包含 400 行的 PDF 文档来进行拆分。
我不知道有哪个函数会以 data.frame 作为输入来渲染所请求的图。我的方法将制作 data.frame 的矩阵掩码,然后使用 lasagnar
package on github 中的 lasagna()
。 lasagna()
是函数 image( t(X)[, (nrow(X):1)] )
的包装器,其中 X
是一个矩阵。此调用对行进行重新排序,以便它们与 data.frame 的顺序相匹配,并且包装器允许切换网格线和添加图例(legend=TRUE 将调用 image.plot( t(X)[, (nrow(X):1)] )
——但是,在示例中下面我明确添加了一个不使用 image.plot()) 的图例。
任务的库
library(fields)
library(colorspace)
library(lubridate)
library(devtools)
install_github("swihart/lasagnar")
library(lasagnar)
创建一个 50 行的示例数据框(400K 示例之前的婴儿示例)
df.in <- data.frame(date=seq(ymd('2012-04-07'),ymd('2013-03-22'),
by = '1 week'),
col1=rnorm(50),
col2=rnorm(50),
col3=rnorm(50),
col4=rnorm(50),
col5=as.factor(c("A","B")),
col6=as.factor(c("MS","PHD")),
col7=rnorm(50),
col8=(c("cherlene","randy")),
col9=rnorm(50),
stringsAsFactors=FALSE)
导致缺失
df.in[19:23 , 2:4 ] <- NA
df.in[c(7, 9), ] <- NA
df.in[2:30 , 4 ] <- NA
df.in[10 , 7 ] <- NA
df.in[14 , 6:10 ] <- NA
检查结构
str(df.in)
准备掩模矩阵
mat.out <- matrix(NA, nrow=nrow(df.in), ncol=ncol(df.in))
然后循环浏览类型列;在末尾应用 is.na()
## red for dates
mat.out[,sapply(df.in,is.POSIXct)] <- 1
## blue for factors
mat.out[,sapply(df.in,is.factor)] <- 2
## green for characters
mat.out[,sapply(df.in,is.character)] <- 3
## white for numeric
mat.out[,sapply(df.in,is.numeric)] <- 4
## black for NA
mat.out[is.na(df.in)] <- 5
行名可能有助于追溯到原始数据
row.names(mat.out) <- 1:nrow(df.in)
render { lasagna(X) 是 image( t(X)[ (nrow(X):1)] ) }
的包装器
lasagna(mat.out, col=c("red","blue","green","white","black"),
cex=0.67, main="")
传说是可能的:
lasagna(mat.out, col=c("red","blue","green","white","black"),
cex=.67, main="")
legend("bottom", fill=c("red","blue","green","white","black"),
legend=c("dates", "factors", "characters", "numeric", "NA"),
horiz=T, xpd=NA, inset=c(-.15), border="black")
使用 gridlines=FALSE 关闭网格线
lasagna(mat.out, col=c("red","blue","green","white","black"),
cex=.67, main="", gridlines=FALSE)
legend("bottom", fill=c("red","blue","green","white","black"),
legend=c("dates", "factors", "characters", "numeric", "NA"),
horiz=T, xpd=NA, inset=c(-.15), border="black")
我们来做一个OP数据大小的例子:400,000行x 50列
创建示例数据框
df2.10 <- data.frame(date=seq(ymd('2012-04-07'),ymd('2013-03-22'),
by = '1 week'),
col1=rnorm(400000),
col2=rnorm(400000),
col3=rnorm(400000),
col4=rnorm(400000),
col5=as.factor(c("A","B")),
col6=as.factor(c("MS","PHD")),
col7=rnorm(400000),
col8=(c("cherlene","randy")),
col9=rnorm(400000),
stringsAsFactors=FALSE)
导致缺失
df2.10[c(19:23), c(2:4) ] <- NA
df2.10[c(7, 9), ] <- NA
df2.10[c(2:30), 4 ] <- NA
df2.10[10 , 7 ] <- NA
df2.10[14 , c(6:10) ] <- NA
df2.10[c(450:750), ] <- NA
df2.10[c(399990:399999), ] <- NA
cbind 为 50 列宽的 df;检查结构
df2.in <- cbind(df2.10, df2.10, df2.10, df2.10, df2.10)
str(df2.in)
准备掩码矩阵
mat.out <- matrix(NA, nrow=nrow(df2.in), ncol=ncol(df2.in))
然后循环浏览类型列;在末尾应用 is.na()
## red for dates
mat.out[,sapply(df2.in,is.POSIXct)] <- 1
## blue for factors
mat.out[,sapply(df2.in,is.factor)] <- 2
## green for characters
mat.out[,sapply(df2.in,is.character)] <- 3
## white for numeric
mat.out[,sapply(df2.in,is.numeric)] <- 4
## black for NA
mat.out[is.na(df2.in)] <- 5
行名可能有助于追溯到原始数据
row.names(mat.out) <- 1:nrow(df2.in)
render { lasagna_plain(X) 没有网格线或行名 }
pdf("pages1000.pdf")
system.time(
for(i in 1:1000){
lasagna_plain(mat.out[((i-1)*400+1):(400*i),],
col=c("red","blue","green","white","black"), cex=1,
main=paste0("rows: ", (i-1)*400+1, " - ", (400*i)))
}
)
dev.off()
for 循环在我的机器上完成了 40 秒,之后很快就完成了 PDF。现在只需在 PDF 查看器中标准化页面大小后向下翻页,查看 pages/plots 例如:
试一试。
require(Amelia)
data(freetrade)
missmap(freetrade)
它不会做红色、蓝色和绿色,但它会得到你的网格。我还会试一试 VIM 包,因为它提供了多种可视化缺失数据的选项。
http://www.statistik.tuwien.ac.at/forschung/CS/CS-2008-1complete.pdf
我有一个大型数据框 (400000 x 50),我想对其结构进行目视检查,blanks/gaps。
有没有现成的库或ggplot2函数,可以吐出这样的图:
红色可能是 "Dates",蓝色可能是 "factors",绿色可能是 "characters",黑色可能是 blanks/NAs。
假设您所说的 blank/gaps 是缺失值 (NA)
image(t(as.matrix(is.na(df))))
您可能想看看 tabplot
包。这么大的 data.frame
加载需要一段时间,但它应该也能正确识别缺失值。更多信息 here。
这是一个使用钻石 data.frame
的图像示例。
编辑
我刚看到你说你的 df 有 50 列。我在那个尺寸的 df 上使用了 tabplot,发现信息的分辨率受屏幕宽度的限制。行数也可能是一个问题,但我个人发现如果 df 太宽,则会丢失更多信息。因此,我建议您将其解析为 3 个单独的 df(例如使用 dplyr
),然后通过 tabplot
或类似的 tableplot()
函数将它们 运行。
您在 lasagnar
中尝试过 dfviewr
吗?下面重现包中 50 行 x 10 列 df.in
所需的图形:
library(devtools)
install_github("swihart/lasagnar")
library(lasagnar)
dfviewr(df=df.in)
## also try:
##dfviewr(df=df.in, legend=FALSE)
##dfviewr(df=df.in, gridlines=FALSE)
所以,公平地说,dfviewr
在提出问题时并不存在,但要了解导致其发展的一些想法以及如何实际可视化 400,000 行,请参阅 for - 在最底部循环,不要太鲁莽 运行 df2.in
(400,000 x 50):
## Do not run:
## system.time(dfviewr(df=df2.in, gridlines=FALSE)) ## 10 minutes before useRaster=TRUE
## 2 minutes after
此外,tabplot:::tableplot()
似乎不支持日期或字符:
library(tabplot)
tableplot(df.in)
产生:
Error in ff(initdata = initdata, length = length, levels = levels, ordered = ordered, : vmode 'character' not implemented
所以我们删除字符列 (#9):
tableplot(df.in[,c(-9)])
产生:
Error in UseMethod("as.hi") :
no applicable method for 'as.hi' applied to an object of class "c('POSIXct', 'POSIXt')"
所以我们也删除了第一列(日期):
tableplot(df.in[,c(-1,-9)])
并获得
对于没有日期或字符列的 400,000 x 50 df2.in
,图像渲染速度非常快(6 秒):
system.time(tableplot(df2.in[,c(-(1+seq(0,40,10)), -(9+seq(0,40,10))) ]))
感兴趣的 reader...
我首先展示一个 50 行的婴儿示例,然后是 400,000 行的示例。
对于它的价值,我支持@cmbarbu 的评论,即在同一个绘图上视觉查看 400K 行受到屏幕的限制,该屏幕最多具有 2K 像素的高度,因此可能会出现某种跨页面分离的情况有利于防止重叠。我尝试通过在 1000 plots/pages 中制作一个包含 400 行的 PDF 文档来进行拆分。
我不知道有哪个函数会以 data.frame 作为输入来渲染所请求的图。我的方法将制作 data.frame 的矩阵掩码,然后使用 lasagnar
package on github 中的 lasagna()
。 lasagna()
是函数 image( t(X)[, (nrow(X):1)] )
的包装器,其中 X
是一个矩阵。此调用对行进行重新排序,以便它们与 data.frame 的顺序相匹配,并且包装器允许切换网格线和添加图例(legend=TRUE 将调用 image.plot( t(X)[, (nrow(X):1)] )
——但是,在示例中下面我明确添加了一个不使用 image.plot()) 的图例。
任务的库
library(fields)
library(colorspace)
library(lubridate)
library(devtools)
install_github("swihart/lasagnar")
library(lasagnar)
创建一个 50 行的示例数据框(400K 示例之前的婴儿示例)
df.in <- data.frame(date=seq(ymd('2012-04-07'),ymd('2013-03-22'),
by = '1 week'),
col1=rnorm(50),
col2=rnorm(50),
col3=rnorm(50),
col4=rnorm(50),
col5=as.factor(c("A","B")),
col6=as.factor(c("MS","PHD")),
col7=rnorm(50),
col8=(c("cherlene","randy")),
col9=rnorm(50),
stringsAsFactors=FALSE)
导致缺失
df.in[19:23 , 2:4 ] <- NA
df.in[c(7, 9), ] <- NA
df.in[2:30 , 4 ] <- NA
df.in[10 , 7 ] <- NA
df.in[14 , 6:10 ] <- NA
检查结构
str(df.in)
准备掩模矩阵
mat.out <- matrix(NA, nrow=nrow(df.in), ncol=ncol(df.in))
然后循环浏览类型列;在末尾应用 is.na()
## red for dates
mat.out[,sapply(df.in,is.POSIXct)] <- 1
## blue for factors
mat.out[,sapply(df.in,is.factor)] <- 2
## green for characters
mat.out[,sapply(df.in,is.character)] <- 3
## white for numeric
mat.out[,sapply(df.in,is.numeric)] <- 4
## black for NA
mat.out[is.na(df.in)] <- 5
行名可能有助于追溯到原始数据
row.names(mat.out) <- 1:nrow(df.in)
render { lasagna(X) 是 image( t(X)[ (nrow(X):1)] ) }
的包装器lasagna(mat.out, col=c("red","blue","green","white","black"),
cex=0.67, main="")
传说是可能的:
lasagna(mat.out, col=c("red","blue","green","white","black"),
cex=.67, main="")
legend("bottom", fill=c("red","blue","green","white","black"),
legend=c("dates", "factors", "characters", "numeric", "NA"),
horiz=T, xpd=NA, inset=c(-.15), border="black")
使用 gridlines=FALSE 关闭网格线
lasagna(mat.out, col=c("red","blue","green","white","black"),
cex=.67, main="", gridlines=FALSE)
legend("bottom", fill=c("red","blue","green","white","black"),
legend=c("dates", "factors", "characters", "numeric", "NA"),
horiz=T, xpd=NA, inset=c(-.15), border="black")
我们来做一个OP数据大小的例子:400,000行x 50列
创建示例数据框
df2.10 <- data.frame(date=seq(ymd('2012-04-07'),ymd('2013-03-22'),
by = '1 week'),
col1=rnorm(400000),
col2=rnorm(400000),
col3=rnorm(400000),
col4=rnorm(400000),
col5=as.factor(c("A","B")),
col6=as.factor(c("MS","PHD")),
col7=rnorm(400000),
col8=(c("cherlene","randy")),
col9=rnorm(400000),
stringsAsFactors=FALSE)
导致缺失
df2.10[c(19:23), c(2:4) ] <- NA
df2.10[c(7, 9), ] <- NA
df2.10[c(2:30), 4 ] <- NA
df2.10[10 , 7 ] <- NA
df2.10[14 , c(6:10) ] <- NA
df2.10[c(450:750), ] <- NA
df2.10[c(399990:399999), ] <- NA
cbind 为 50 列宽的 df;检查结构
df2.in <- cbind(df2.10, df2.10, df2.10, df2.10, df2.10)
str(df2.in)
准备掩码矩阵
mat.out <- matrix(NA, nrow=nrow(df2.in), ncol=ncol(df2.in))
然后循环浏览类型列;在末尾应用 is.na()
## red for dates
mat.out[,sapply(df2.in,is.POSIXct)] <- 1
## blue for factors
mat.out[,sapply(df2.in,is.factor)] <- 2
## green for characters
mat.out[,sapply(df2.in,is.character)] <- 3
## white for numeric
mat.out[,sapply(df2.in,is.numeric)] <- 4
## black for NA
mat.out[is.na(df2.in)] <- 5
行名可能有助于追溯到原始数据
row.names(mat.out) <- 1:nrow(df2.in)
render { lasagna_plain(X) 没有网格线或行名 }
pdf("pages1000.pdf")
system.time(
for(i in 1:1000){
lasagna_plain(mat.out[((i-1)*400+1):(400*i),],
col=c("red","blue","green","white","black"), cex=1,
main=paste0("rows: ", (i-1)*400+1, " - ", (400*i)))
}
)
dev.off()
for 循环在我的机器上完成了 40 秒,之后很快就完成了 PDF。现在只需在 PDF 查看器中标准化页面大小后向下翻页,查看 pages/plots 例如:
试一试。
require(Amelia)
data(freetrade)
missmap(freetrade)
它不会做红色、蓝色和绿色,但它会得到你的网格。我还会试一试 VIM 包,因为它提供了多种可视化缺失数据的选项。
http://www.statistik.tuwien.ac.at/forschung/CS/CS-2008-1complete.pdf