#json #r #dataframe
#json #r #фрейм данных
Вопрос:
Я анализирую структуру данных, которая выглядит следующим образом в R:
[
{ 'firstName': 'abc', 'lastName' : 'def' },
{ 'firstName': 'abc2', 'lastName' : 'def2' }
]
Я хочу сохранить эти данные во фрейме данных. Мой текущий подход ошибочен и кажется действительно грязным. У меня есть несколько наборов данных, но мне нужно указать столбцы. Кто-нибудь может предложить что-то «более чистое»?
Проблема 1: Мне нужно указать имена данных
library(rjson)
listData <- fromJSON(jsonData)
listNames <- c('firstName', 'lastName')
for (player in listData){
playerCols = c()
for (name in listNames){
value <- player[[name]]
if (is.null(value}{value <- "NA"}
playerCols <- c(playerCols, value)
}
# code to convert playerCols to data.frame currently goes here.
}
Я хотел бы выполнить это извлечение, если это возможно, без использования имен столбцов или таким образом, чтобы я извлекал столбцы из этих данных по ходу работы. Сложность здесь заключается в том, что не все столбцы заполняются в каждой записи. Я бы хотел, чтобы конечный фрейм данных знал все столбцы и устанавливал пропущенные значения в NA
Проблема 2: кажется, мне не удается добавить строку данных, вместо этого списки создаются в виде столбцов
for (player in listData){
# code to extract columns here
df = data.frame(playerCols, name=listNames)
print(df)
}
Вместо создания фрейма данных из 2 столбцов со строками, содержащими все данные и все имена, мне нужна одна строка с именованными столбцами, которые я затем могу rbind
объединить.
Ответ №1:
Почти всегда это плохая идея — пытаться построить data.frame построчно. Это просто неэффективный процесс. Лучше строить свои данные по столбцам и объединять их в data.frame в конце. Во-первых, давайте воспользуемся некоторыми примерами данных, которые на самом деле содержат пропущенные значения, как вы описали
a<-'[
{ "firstName": "abc", "lastName" : "def" },
{ "firstName": "abc2" }
]'
Давайте также создадим вспомогательную функцию, которая извлечет значение из списка, если оно существует, или вернет NA, если оно не существует
extr<-function(list,ele) {
x<-list[[ele]]
if (is.null(x)) x=NA;
x
}
Если вы хотите получить все значения без явного указания имен тегов, вы можете найти их с помощью
listNames <- unique(unlist(lapply(listData, names)))
Теперь мы можем преобразовать json в список, а затем каждый раз извлекать вектор значений столбцов и, наконец, объединять их в data.frame с помощью
listData <- fromJSON(a)
data.frame(Map(function(n) sapply(listData, extr, n), listNames))
Здесь я использую Map
, а не более привычный lapply
, потому что он будет правильно использовать значения listNames
в качестве имен для возвращаемого списка.
Комментарии:
1. Идеально, что сработало, за одним исключением —
c(sapply(listData, names))
вместо использованияunlist