从 R 中的弹性搜索结果中取消列表列表
Unnest lists of list from an elastic Search result in R
编辑 1:问题更简单(对于整个问题,请查看原始编辑)
如何取消列出数据框中的键值对列表,知道键值对的数量可能会有所不同。
例如:
_source.types _source.label
1 key1, key2, value1, value2 label1
2 NULL label1
3 key3, value3 label2
注意 (key1, key2, value1, value2) 是一个 <data.frame>
预期结果:
types.k1 types.v1 types.k2 types.v2 label
1 key1 value1 key2 value2 label1
2 NULL NULL NULL NULL label1
3 key3 value3 NULL NULL label2
我已经尝试了 unnest
、unlist
、...但都没有成功,因为我总是因为元素数量或对象的 class 而出错。
原始编辑
我使用弹性包向弹性搜索库发出搜索请求的结果。由于查询是来自预先存在的数据框中的术语的循环,因此我有每个术语的响应列表。
#existing dataframe
df <- data.frame(id=c("1","2"),terms=(c("Guy de Maupassant","Vincent Cassel")))
#loop query to ES
query_es <- '{"_source": ["id", "label", "types", "subTypes"],
"query":{"bool":{"must":[{"term":{"label":"%s"}}]}}}'
out = list()
for (i in seq_along(df$terms)) {
out[[i]] <- Search(index = "index_1",
body = sprintf(query_es, df$terms[i]),
size = 3, asdf=TRUE)$hits$hits
}
结果是这样的列表列表(为了清楚起见,我只显示第一个结果):
[[1]]
_index _type _id _score _source.types
1 index_1 triplet Q9327 13.18037 Q5, dbPedia.Person, être humain, personne
2 index_1 triplet Q3122270 13.17847 Q11424, dbPedia.Film, film, film
_source.subTypes _source.label _source.id
1 Q1930187, Q36180, Q15949613, Q6625963, Q214917, journaliste, écrivain, nouvelliste, romancier, dramaturge Guy de Maupassant Q9327
2 NULL Guy de Maupassant Q3122270
如您所见,第一个术语有 2 个可能的结果:作家或电影,每个都有类型和子类型的 {id,value} 列表。
为了看得更全面,我重新整理了输出:
out2 <- bind_rows(out, .id = "id")
out2 <- out_i_bind2[,-c(2:5)]
colnames(out2) <- c("id","types","subTypes","entityLabel","entityId")
因此,我有(仅第一学期):
id types
1 1 Q5, dbPedia.Person, être humain, personne
2 1 Q11424, dbPedia.Film, film, film
subTypes entityLabel entityId
1 Q1930187, Q36180, Q15949613, Q6625963, Q214917, journaliste, écrivain, nouvelliste, romancier, dramaturge Guy de Maupassant Q9327
2 NULL Guy de Maupassant Q3122270
请注意,对于第二个结果(电影),我没有任何子类型。此外,类型或子类型中列出的元素的长度可能会因搜索词而异。
现在,我想取消嵌套列表以获得这样的数据框(抱歉格式不是很全面,但基本上我的想法是让每个{ key,value} unnested in 2 columns with a incremental index):
X_id X_source.types.id X_source.types.value X_source.types.id.1 X_source.types.value.1 X_source.subTypes.id
1 1 Q5 être humain dbPedia.Person personne Q1930187
2 1 Q11424 film dbPedia.Film film <NA>
X_source.subTypes.value X_source.subTypes.id.1 X_source.subTypes.value.1 X_source.subTypes.id.2 X_source.subTypes.value.2
1 journaliste Q36180 écrivain Q15949613 nouvelliste
2 <NA> <NA> <NA> <NA> <NA>
X_source.subTypes.id.3 X_source.subTypes.value.3 X_source.subTypes.id.4 X_source.subTypes.value.4 X_source.label X_source.id
1 Q6625963 romancier Q214917 dramaturge Guy de Maupassant Q9327
2 <NA> <NA> <NA> <NA> Guy de Maupassant Q3122270
相关id的保存很重要。我尝试了很多在这里找到的东西:
Convert in R output of package Elastic (nested list?) to data.frame or JSON
或在这里:
没有任何成功...
有什么办法处理吗?我想知道我是否应该转换重新排列的输出 (out2) 还是返回原始输出 (out) 更好...
提前致谢!
PS :这里是 "out" 的输出版本(来自 df Search):
> dput(out, control="useSource")
list(list(`_index` = c("alias_fr", "alias_fr"), `_type` = c("triplet",
"triplet"), `_id` = c("Q9327", "Q3122270"), `_score` = c(13.180366,
13.178474), `_source.types` = list(list(id = c("Q5", "dbPedia.Person"
), value = c("être humain", "personne")), list(id = c("Q11424",
"dbPedia.Film"), value = c("film", "film"))), `_source.subTypes` = list(
list(id = c("Q1930187", "Q36180", "Q15949613", "Q6625963",
"Q214917"), value = c("journaliste", "écrivain", "nouvelliste",
"romancier", "dramaturge")), NULL), `_source.label` = c("Guy de Maupassant",
"Guy de Maupassant"), `_source.id` = c("Q9327", "Q3122270")),
list(`_index` = "alias_fr", `_type` = "triplet", `_id` = "Q193504",
`_score` = 13.18018, `_source.types` = list(list(id = c("Q5",
"dbPedia.Person"), value = c("être humain", "personne"
))), `_source.subTypes` = list(list(id = c("Q33999",
"Q10800557", "Q3282637", "Q2526255", "Q28389"), value = c("acteur",
"acteur de cinéma", "producteur de cinéma", "réalisateur",
"scénariste"))), `_source.label` = "Vincent Cassel",
`_source.id` = "Q193504"))
out2 也一样:
> dput(out2, control="useSource")
list(id = c("1", "1", "2"), types = list(list(id = c("Q5", "dbPedia.Person"
), value = c("être humain", "personne")), list(id = c("Q11424",
"dbPedia.Film"), value = c("film", "film")), list(id = c("Q5",
"dbPedia.Person"), value = c("être humain", "personne"))), subTypes = list(
list(id = c("Q1930187", "Q36180", "Q15949613", "Q6625963",
"Q214917"), value = c("journaliste", "écrivain", "nouvelliste",
"romancier", "dramaturge")), NULL, list(id = c("Q33999",
"Q10800557", "Q3282637", "Q2526255", "Q28389"), value = c("acteur",
"acteur de cinéma", "producteur de cinéma", "réalisateur",
"scénariste"))), entityLabel = c("Guy de Maupassant", "Guy de Maupassant",
"Vincent Cassel"), entityId = c("Q9327", "Q3122270", "Q193504"
))
由于和一些改造步骤,我终于设法解决了问题。虽然解决方案不是很优雅,但它有效:
out_bind <- bind_rows(out, .id = "id")
#transform to data table in order to apply rbindlist
out <- as.data.table(out_bind)
#rbindlist for "types" variable
out_nest1 <- rbindlist(out$types, fill = T, id = "row")[, entityId := out$entityId[row]][]
#rbindlist to "subTypes variable (choosing another id name -row1-, if not Rstudio was crashing!)
out_nest2 <- rbindlist(out$subTypes, fill = T, id = "row1")[, entityId := out$entityId[row1]][]
#finally joining the whole data
out <- full_join(out,out_nest1,by="entityId")
out <- full_join(out,out_nest2,by="entityId")
现在我可以度过一个愉快的圣诞节了;)
编辑:崩溃不是由于 id 名称,而是由于 data.table 问题,已解决 。
编辑 1:问题更简单(对于整个问题,请查看原始编辑)
如何取消列出数据框中的键值对列表,知道键值对的数量可能会有所不同。
例如:
_source.types _source.label
1 key1, key2, value1, value2 label1
2 NULL label1
3 key3, value3 label2
注意 (key1, key2, value1, value2) 是一个 <data.frame>
预期结果:
types.k1 types.v1 types.k2 types.v2 label
1 key1 value1 key2 value2 label1
2 NULL NULL NULL NULL label1
3 key3 value3 NULL NULL label2
我已经尝试了 unnest
、unlist
、...但都没有成功,因为我总是因为元素数量或对象的 class 而出错。
原始编辑 我使用弹性包向弹性搜索库发出搜索请求的结果。由于查询是来自预先存在的数据框中的术语的循环,因此我有每个术语的响应列表。
#existing dataframe
df <- data.frame(id=c("1","2"),terms=(c("Guy de Maupassant","Vincent Cassel")))
#loop query to ES
query_es <- '{"_source": ["id", "label", "types", "subTypes"],
"query":{"bool":{"must":[{"term":{"label":"%s"}}]}}}'
out = list()
for (i in seq_along(df$terms)) {
out[[i]] <- Search(index = "index_1",
body = sprintf(query_es, df$terms[i]),
size = 3, asdf=TRUE)$hits$hits
}
结果是这样的列表列表(为了清楚起见,我只显示第一个结果):
[[1]]
_index _type _id _score _source.types
1 index_1 triplet Q9327 13.18037 Q5, dbPedia.Person, être humain, personne
2 index_1 triplet Q3122270 13.17847 Q11424, dbPedia.Film, film, film
_source.subTypes _source.label _source.id
1 Q1930187, Q36180, Q15949613, Q6625963, Q214917, journaliste, écrivain, nouvelliste, romancier, dramaturge Guy de Maupassant Q9327
2 NULL Guy de Maupassant Q3122270
如您所见,第一个术语有 2 个可能的结果:作家或电影,每个都有类型和子类型的 {id,value} 列表。 为了看得更全面,我重新整理了输出:
out2 <- bind_rows(out, .id = "id")
out2 <- out_i_bind2[,-c(2:5)]
colnames(out2) <- c("id","types","subTypes","entityLabel","entityId")
因此,我有(仅第一学期):
id types
1 1 Q5, dbPedia.Person, être humain, personne
2 1 Q11424, dbPedia.Film, film, film
subTypes entityLabel entityId
1 Q1930187, Q36180, Q15949613, Q6625963, Q214917, journaliste, écrivain, nouvelliste, romancier, dramaturge Guy de Maupassant Q9327
2 NULL Guy de Maupassant Q3122270
请注意,对于第二个结果(电影),我没有任何子类型。此外,类型或子类型中列出的元素的长度可能会因搜索词而异。
现在,我想取消嵌套列表以获得这样的数据框(抱歉格式不是很全面,但基本上我的想法是让每个{ key,value} unnested in 2 columns with a incremental index):
X_id X_source.types.id X_source.types.value X_source.types.id.1 X_source.types.value.1 X_source.subTypes.id
1 1 Q5 être humain dbPedia.Person personne Q1930187
2 1 Q11424 film dbPedia.Film film <NA>
X_source.subTypes.value X_source.subTypes.id.1 X_source.subTypes.value.1 X_source.subTypes.id.2 X_source.subTypes.value.2
1 journaliste Q36180 écrivain Q15949613 nouvelliste
2 <NA> <NA> <NA> <NA> <NA>
X_source.subTypes.id.3 X_source.subTypes.value.3 X_source.subTypes.id.4 X_source.subTypes.value.4 X_source.label X_source.id
1 Q6625963 romancier Q214917 dramaturge Guy de Maupassant Q9327
2 <NA> <NA> <NA> <NA> Guy de Maupassant Q3122270
相关id的保存很重要。我尝试了很多在这里找到的东西:
Convert in R output of package Elastic (nested list?) to data.frame or JSON
或在这里:
有什么办法处理吗?我想知道我是否应该转换重新排列的输出 (out2) 还是返回原始输出 (out) 更好...
提前致谢!
PS :这里是 "out" 的输出版本(来自 df Search):
> dput(out, control="useSource")
list(list(`_index` = c("alias_fr", "alias_fr"), `_type` = c("triplet",
"triplet"), `_id` = c("Q9327", "Q3122270"), `_score` = c(13.180366,
13.178474), `_source.types` = list(list(id = c("Q5", "dbPedia.Person"
), value = c("être humain", "personne")), list(id = c("Q11424",
"dbPedia.Film"), value = c("film", "film"))), `_source.subTypes` = list(
list(id = c("Q1930187", "Q36180", "Q15949613", "Q6625963",
"Q214917"), value = c("journaliste", "écrivain", "nouvelliste",
"romancier", "dramaturge")), NULL), `_source.label` = c("Guy de Maupassant",
"Guy de Maupassant"), `_source.id` = c("Q9327", "Q3122270")),
list(`_index` = "alias_fr", `_type` = "triplet", `_id` = "Q193504",
`_score` = 13.18018, `_source.types` = list(list(id = c("Q5",
"dbPedia.Person"), value = c("être humain", "personne"
))), `_source.subTypes` = list(list(id = c("Q33999",
"Q10800557", "Q3282637", "Q2526255", "Q28389"), value = c("acteur",
"acteur de cinéma", "producteur de cinéma", "réalisateur",
"scénariste"))), `_source.label` = "Vincent Cassel",
`_source.id` = "Q193504"))
out2 也一样:
> dput(out2, control="useSource")
list(id = c("1", "1", "2"), types = list(list(id = c("Q5", "dbPedia.Person"
), value = c("être humain", "personne")), list(id = c("Q11424",
"dbPedia.Film"), value = c("film", "film")), list(id = c("Q5",
"dbPedia.Person"), value = c("être humain", "personne"))), subTypes = list(
list(id = c("Q1930187", "Q36180", "Q15949613", "Q6625963",
"Q214917"), value = c("journaliste", "écrivain", "nouvelliste",
"romancier", "dramaturge")), NULL, list(id = c("Q33999",
"Q10800557", "Q3282637", "Q2526255", "Q28389"), value = c("acteur",
"acteur de cinéma", "producteur de cinéma", "réalisateur",
"scénariste"))), entityLabel = c("Guy de Maupassant", "Guy de Maupassant",
"Vincent Cassel"), entityId = c("Q9327", "Q3122270", "Q193504"
))
由于
out_bind <- bind_rows(out, .id = "id")
#transform to data table in order to apply rbindlist
out <- as.data.table(out_bind)
#rbindlist for "types" variable
out_nest1 <- rbindlist(out$types, fill = T, id = "row")[, entityId := out$entityId[row]][]
#rbindlist to "subTypes variable (choosing another id name -row1-, if not Rstudio was crashing!)
out_nest2 <- rbindlist(out$subTypes, fill = T, id = "row1")[, entityId := out$entityId[row1]][]
#finally joining the whole data
out <- full_join(out,out_nest1,by="entityId")
out <- full_join(out,out_nest2,by="entityId")
现在我可以度过一个愉快的圣诞节了;)
编辑:崩溃不是由于 id 名称,而是由于 data.table 问题,已解决