Mongolite неправильно вставляет фрейм данных со столбцом списка в БД Mongo - PullRequest
0 голосов
/ 15 октября 2018

Собираюсь сделать короткий, воспроизводимый пример проблемы, которая возникает у меня, которая заключается в вставке данных из R в базу данных Монго.Это сложно, потому что, как вы увидите, у меня есть вложенный столбец данных.Исправление этого имеет решающее значение для моей базы данных, и я думаю, что это проблема, с которой могут столкнуться и другие.

Мои данные:

my.data <- structure(list(`_id` = c(10138L, 9466L, 9390L), firstName = c("Alex", "Quincy", "Steven"), lastName = c("Abrines", "Acy", "Adams"), 
    birthCity = c("Palma de Mallorca", "Tyler, TX", "Rotorua"
    ), birthCountry = c("Spain", "USA", "New Zealand")), row.names = c(NA, 
3L), class = "data.frame")

my.data
> nba_players
    _id firstName lastName         birthCity birthCountry
1 10138      Alex  Abrines Palma de Mallorca        Spain
2  9466    Quincy      Acy         Tyler, TX          USA
3  9390    Steven    Adams           Rotorua  New Zealand

inner.df <- structure(list(jerseyNumber = 40L, weight = 240L, age = 21L), class = "data.frame", row.names = 485L)

num.vector <- c(1,3,5,7)

Моя цель с вышеизложенным двоякая:

  • добавить 4-й столбец к inner.df, в котором num.vector
  • добавить inner.df в качестве 6-го столбца к каждой строке в my.data

... и вот код, который я использую для этого:

# add a list of the numbers to inner df
inner.df$shotIDs = list(num.vector)  

# create allmonths column (name of the row where inner.df's will be placed)  
my.data <- my.data %>%
  dplyr::mutate(allmonths = NA)

# convert allmonths into a column of class == list
my.data$allmonths[1] = list(placeholder = NA)

# For EACH row in my main my.data dataframe, add the inner.df to the allmonths column/key
for(i in 1:nrow(my.data)) {
  my.data$allmonths[[i]] <- inner.df
}

# Write this to my mongo db
con <- mongolite::mongo(collection = 'mycoll', db = 'mydb', url = "myurl")
con$insert(my.data) # this is not a good way to update a db

Вот мой результат (показанный в Robo 3T):

enter image description here ...

Я так близко с этим, но по какой-то причине allmonths является массивом длины 1, а не своим собственным объектом.Если бы allmonths был объектом с 4 полями, с такими же значениями, что и у объекта, помеченного [0], то это было бы намного лучше.

Кто-нибудь видит, что не так в моей попытке здесь.Я уверен, что это проблема, с которой другие могли столкнуться при работе с вложенными объектами в R!Любая помощь очень ценится!

1 Ответ

0 голосов
/ 16 октября 2018

Чтобы получить объект { }, ваш allmonths должен быть столбцом типа data.frame, а не list.

Принимая ваш пример

library(dplyr)

my.data <- structure(list(`_id` = c(10138L, 9466L, 9390L), firstName = c("Alex", "Quincy", "Steven"), lastName = c("Abrines", "Acy", "Adams"), 
                          birthCity = c("Palma de Mallorca", "Tyler, TX", "Rotorua"
                          ), birthCountry = c("Spain", "USA", "New Zealand")), row.names = c(NA, 
                                                                                             3L), class = "data.frame")


my.data

inner.df <- structure(list(jerseyNumber = 40L, weight = 240L, age = 21L), class = "data.frame", row.names = 485L)

num.vector <- c(1,3,5,7)

# add a list of the numbers to inner df
inner.df$shotIDs = list(num.vector)  

Если вы сейчас добавите свой inner.df в виде столбца (нужно повторить его, потому что вам нужно 3 строки, чтобы соответствовать вашему my.data)

my.data$allmonths <- inner.df[rep(1,3), ]

А затем просмотрите JSON, который он производит, и увидите, что вы получаете allmonths: { } объект

substr( jsonlite::toJSON( my.data ), 1, 196 )
# [{"_id":10138,"firstName":"Alex","lastName":"Abrines","birthCity":"Palma de Mallorca","birthCountry":"Spain",
# "allmonths":{"jerseyNumber":40,"weight":240,"age":21,"shotIDs":[1,3,5,7],"_row":"485"}
# } 

В стороне

Часто полезно создать JSON you 'после этого, затем позвоните fromJSON, чтобы увидеть структуру R, к которой вы должны стремиться

js <- '
[{"_id":10138,"firstName":"Alex","lastName":"Abrines","birthCity":"Palma de Mallorca","birthCountry":"Spain","allmonths":{"jerseyNumber":40,"weight":240,"age":21,"shotIDs":[1,3,5,7],"_row":"485"}},{"_id":9466,"firstName":"Quincy","lastName":"Acy","birthCity":"Tyler, TX","birthCountry":"USA","allmonths":{"jerseyNumber":40,"weight":240,"age":21,"shotIDs":[1,3,5,7],"_row":"485.1"}},{"_id":9390,"firstName":"Steven","lastName":"Adams","birthCity":"Rotorua","birthCountry":"New Zealand","allmonths":{"jerseyNumber":40,"weight":240,"age":21,"shotIDs":[1,3,5,7],"_row":"485.2"}}] 
'
str( jsonlite::fromJSON( js ) )

# 'data.frame': 3 obs. of  6 variables:
#   $ _id         : int  10138 9466 9390
#   $ firstName   : chr  "Alex" "Quincy" "Steven"
#   $ lastName    : chr  "Abrines" "Acy" "Adams"
#   $ birthCity   : chr  "Palma de Mallorca" "Tyler, TX" "Rotorua"
#   $ birthCountry: chr  "Spain" "USA" "New Zealand"
#   $ allmonths   :'data.frame':    3 obs. of  4 variables:
#   ..$ jerseyNumber: int  40 40 40
#   ..$ weight      : int  240 240 240
#   ..$ age         : int  21 21 21
#   ..$ shotIDs     :List of 3
#   .. ..$ : int  1 3 5 7
#   .. ..$ : int  1 3 5 7
#   .. ..$ : int  1 3 5 7
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...