У меня есть список, как это:Преобразование списка смешанных элементов класса для фрейма данных, сохраняя при этом класс
list(
structure(
list(
time = structure(
1452841800,
class = c("POSIXct", "POSIXt")
),
latitude = 34.0128987,
longitude = -84.7879747,
location = structure(
list(),
.Names = character(0)
),
day = "FRIDAY"
),
.Names = c("time", "latitude", "longitude", "location", "day")
),
structure(
list(
time = structure(
1456875240,
class = c("POSIXct", "POSIXt")
),
latitude = 35.85285882,
longitude = -78.69758511,
location = structure(
list(
postcode = "27612"
),
.Names = "postcode"
),
day = "TUESDAY"
),
.Names = c("time", "latitude", "longitude", "location", "day")
),
structure(
list(
time = structure(
1456621440,
class = c("POSIXct", "POSIXt")
),
latitude = 33.81418132,
longitude = -84.73134873,
location = structure(
list(
postcode = "30127"
),
.Names = "postcode"
),
day = "SATURDAY"
),
.Names = c("time", "latitude", "longitude", "location", "day")
),
structure(
list(
time = structure(
1451953320,
class = c("POSIXct", "POSIXt")
),
latitude = 33.6678031,
longitude = -86.5398931,
location = structure(
list(
postcode = "35173"
),
.Names = "postcode"
),
day = "MONDAY"
),
.Names = c("time", "latitude", "longitude", "location", "day")
),
structure(
list(
time = structure(
1452966960,
class = c("POSIXct", "POSIXt")
),
latitude = 33.8458767,
longitude = -84.0986578,
location = structure(
list(
postcode = "30047"
),
.Names = "postcode"
),
day = "SATURDAY"
),
.Names = c("time", "latitude", "longitude", "location", "day")
),
structure(
list(
time = structure(
1455584160,
class = c("POSIXct", "POSIXt")
),
latitude = 36.4001153,
longitude = -105.5727933,
location = structure(
list(
postcode = "87571"
),
.Names = "postcode"
),
day = "MONDAY"
),
.Names = c("time", "latitude", "longitude", "location", "day")
)
)
Я хочу, чтобы включить в кадр данных. Я почти добираюсь туда, но имею некоторые проблемы. Когда я удалить элементы списка, которые не являются «числовой», я получаю хороший кадр данных с числовыми столбцами следующим образом:
df <- as.data.frame(
do.call(rbind, lapply(d, function(x) unlist(x[-c(4, 5)]))),
stringsAsFactors = FALSE
)
str(df)
'data.frame': 6 obs. of 3 variables:
$ time : num 1.45e+09 1.46e+09 1.46e+09 1.45e+09 1.45e+09 ...
$ latitude : num 34 35.9 33.8 33.7 33.8 ...
$ longitude: num -84.8 -78.7 -84.7 -86.5 -84.1 ...
До сих пор так хорошо ...
Теперь, когда у меня есть элемент символов в списке, я получаю все столбцы, принуждаемые к классу символов. Не то, что я хочу. Конечно, я могу снова вернуться обратно. Но ...
df <- as.data.frame(
do.call(rbind, lapply(d, function(x) unlist(x[-4]))),
stringsAsFactors = FALSE
)
str(df)
'data.frame': 6 obs. of 4 variables:
$ time : chr "1452841800" "1456875240" "1456621440" "1451953320" ...
$ latitude : chr "34.0128987" "35.85285882" "33.81418132" "33.6678031" ...
$ longitude: chr "-84.7879747" "-78.69758511" "-84.73134873" "-86.5398931" ...
$ day : chr "FRIDAY" "TUESDAY" "SATURDAY" "MONDAY" ...
Наконец, поскольку location$postcode
поле имеет пустой список, весь этот механизм не может даже дать мне правильный кадр данных. Я работаю вокруг него, извлекая из этого поля в отдельности, а столбец привязки его следующим образом:
postcode <- sapply(d, function(x) if (length(x$location)) unlist(x$location) else NA)
df$postcode <- postcode
df
time latitude longitude day postcode
1 1452841800 34.0128987 -84.7879747 FRIDAY <NA>
2 1456875240 35.85285882 -78.69758511 TUESDAY 27612
3 1456621440 33.81418132 -84.73134873 SATURDAY 30127
4 1451953320 33.6678031 -86.5398931 MONDAY 35173
5 1452966960 33.8458767 -84.0986578 SATURDAY 30047
6 1455584160 36.4001153 -105.5727933 MONDAY 87571
Три вопроса:
1) Как сохранить класс при преобразовании моего списка в кадр данных?
2) Есть ли лучший способ справиться с нулевым перечисленными элементами в списке (мой пост поле кода)
3) Если нет другого пути на # 2, есть более эффективный способ сделать то, что я чем один цикл через данные? Я полагаю, я могу совместить нулевой чек-лист на почтовый индекс поля и сцепить в lapply
я использую с do.call(rbind, ...)
EDIT: Для ясности, эти классы названных элементов в моем списке:
sapply(d[[1]], class)
$time
[1] "POSIXct" "POSIXt"
$latitude
[1] "numeric"
$longitude
[1] "numeric"
$location
[1] "list"
$day
[1] "character"
В той степени, в которой «первый» случай работает, сохраняя числовые значения, которые все еще после преобразования моего элемента POSIXct time
в числовой. Я бы предпочел, чтобы он остался нетронутым. :)
См, также, 'do.call (data.frame, C (= stringsAsFactors значение FALSE, .mapply (с, lapply (д, функция (х) {х $ =, если местоположение (длина (х! $ location $ postcode)) NA else x $ location $ postcode; x}), NULL))) ', чтобы избежать принуждения. –
И это невероятно быстро по сравнению с чем-либо еще, что я пробовал выше и выше моего исходного кода. Можете ли вы написать это как ответ, и я соглашусь? Очень хорошо...! – Gopala