2016-11-21 52 views
0

我从elasticsearch提取数据如下:提取数据不扩展到相同长度

> packageVersion("elastic") [1] '0.7.8' 
# data extract 
body <- list(query=list(range=list(timestamp=list(gte="2016-10-13", lte="2016-10-15")))) 
b3 <- Search(index="myIndex", 
     sort=c("timestamp:desc"), 
     fields=c('timestamp','A','B','C','D','E','F','G'), 
     body=body, 
     size=3) 

所述第一和第二元件是提取正常(编辑以节省空间):
$ hits $ hits [[1]] $ fields $ F,E,B,G,C,A,D,时间戳
$ hits $ hits [[2]] $字段$ F,E,B,G,C,A,D,时间戳

第三个元素未被完全提取为:
$ $命中命中[[3]] $ $字段C,A,B,d,时间戳

== 我的列表转换为数据帧按照此信息:
Convert in R output of package Elastic (nested list?) to data.frame or JSON
第一和第二个元素完美加载。
第三元件被错误地装载,因为不完整的元素被提取,使以下错误:

# (optional) verify that all hits expand to the same length 
# (should be true for data intended to be in a table format) 
stopifnot(
sapply(
b3$hits$hits, 
function(x) {!(length(unlist(x)) - length(unlist(b3$hits$hits[[1]])))} 
) 
) 
Error: sapply(b3$hits$hits, function(x) { .... are not all TRUE 

# load into the dataframe 
# count number of columns, use unlist() to convert 
# nested lists to a vector, use the first hit as proxy 
nColumns <- length(unlist(b3$hits$hits[[1]])) 

# fetch column names ... as above 
nNames <- names(unlist(b3$hits$hits[[1]])) 

# unlist all hits and convert to matrix with ncol Columns, don't forget byrow=TRUE! 
df.b3 <- data.frame(matrix(unlist(b3$hits$hits), ncol=nColumns, byrow=TRUE)) 

Warning message: 
In matrix(unlist(b3$hits$hits), ncol = nColumns, byrow = TRUE) : 
data length [33] is not a sub-multiple or multiple of the number of columns [12] 
> 

注:在变量d,E,F,G包含空(NULL)的一些记录和“ - ”值。我怀疑这可能会导致提取问题。

如果你们中的任何一个人遇到类似的问题并找到解决方案,我会很乐意提供一些反馈意见。
非常感谢。这里的elastic

回答

1

作者,我们不要试图强迫输出到data.frame是因为它可以使变量,我们就可能会遇到错误频繁。但我们确实允许您将选项传递给jsonlite以强制为data.frame(通过asdf参数,对于作为data.frame),因为这应该不会失败。

如果处理列表输出,我会使用dplyrdata.table之一来获取列表。

对于重复性:

library(elastic) 
if (!index_exists("shakespeare")) { 
    shakespeare <- system.file("examples", "shakespeare_data.json", package = "elastic") 
    docs_bulk(shakespeare) 
} 
res <- Search(index="shakespeare", fields=c('play_name','speaker')) 
out <- lapply(res$hits$hits, function(x) unlist(x$fields, FALSE)) 

dplyr

library(dplyr) 
bind_rows(out) 
#> # A tibble: 10 × 2 
#> play_name  speaker 
#>  <chr>   <chr> 
#> 1 Henry IV    
#> 2 Henry IV KING HENRY IV 
#> 3 Henry IV KING HENRY IV 
#> 4 Henry IV KING HENRY IV 
#> 5 Henry IV KING HENRY IV 
#> 6 Henry IV KING HENRY IV 
#> 7 Henry IV KING HENRY IV 
#> 8 Henry IV KING HENRY IV 
#> 9 Henry IV WESTMORELAND 
#> 10 Henry IV WESTMORELAND 

data.table

library(data.table) 
rbindlist(out, fill = TRUE, use.names = TRUE) 
#> play_name  speaker 
#> 1: Henry IV    
#> 2: Henry IV KING HENRY IV 
#> 3: Henry IV KING HENRY IV 
#> 4: Henry IV KING HENRY IV 
#> 5: Henry IV KING HENRY IV 
#> 6: Henry IV KING HENRY IV 
#> 7: Henry IV KING HENRY IV 
#> 8: Henry IV KING HENRY IV 
#> 9: Henry IV WESTMORELAND 
#> 10: Henry IV WESTMORELAND 

或者,使用asdf参数,它的内部指引jsonlite::fromJSON如果可能解析到一个data.frame。

res <- Search(index="shakespeare", fields=c('play_name','speaker'), asdf = TRUE) 
res$hits$hits$fields 
#> play_name  speaker 
#> 1 Henry IV    
#> 2 Henry IV KING HENRY IV 
#> 3 Henry IV KING HENRY IV 
#> 4 Henry IV KING HENRY IV 
#> 5 Henry IV KING HENRY IV 
#> 6 Henry IV KING HENRY IV 
#> 7 Henry IV KING HENRY IV 
#> 8 Henry IV KING HENRY IV 
#> 9 Henry IV WESTMORELAND 
#> 10 Henry IV WESTMORELAND 

使用:

  • řv3.3.2
  • OSX
  • elasticv0.7.8.9000
  • Elasticsearchv2.3.4
+0

由于@sckott。 'data.table'和'asdf'非常出色。 我还注意到'sort'参数为我的提取列表中的某些记录创建问题,因为时间戳字段使用'sort'值填充。所以我不使用'sort'参数,我得到了一个完美的输出结果。感谢Scott在过去几周再次为您提供帮助。 – Trina

+0

np,没有听说过'sort'的问题。你用什么意思排序_ value_,你的意思是字符串'sort'在每个时间戳? – sckott

+0

只有几条记录我得到这个:$ hits $ hits [[6]] $ fields $ timestamp $ hits $ hits [[6]] $ fields $ timestamp [[1]] [1] 1476489596109 $点击$ hits [[6]] $ sort $ hits $ hits [[6]] $ sort [[1]] [1] 1476489596109对不起,关于显示。我只是复制时间戳并从一个元素进行排序。 – Trina