#r #dataframe #vector #metadata #mode
#r #dataframe #вектор #метаданные #режим
Вопрос:
У меня есть data.frame в R (давайте в качестве примера используем встроенный набор данных «mtcars»), и я хотел бы найти более эффективный способ создания второго data.frame, содержащего описания каждой переменной (т. Е. Некоторые Базовые метаданные) следующим образом:
Variables Type Labels
mpg numeric Miles/(US) gallon
cyl numeric Number of cylinders
disp numeric Displacement (cu.in.)
hp numeric Gross horsepower
drat numeric Rear axle ratio
wt numeric Weight (1000 lbs)
qsec numeric 1/4 mile time
vs numeric Engine (0 = V-shaped, 1 = straight)
am numeric Transmission (0 = automatic, 1 = manual)
gear numeric Number of forward gears
carb numeric Number of carburetors
Приведенный ниже код указывает мой текущий метод получения data.frame с описаниями каждой переменной, включая имена переменных, типы переменных элементов и метки.
dat01 <- mtcars
Variables <- c(names(dat01))
#install.packages("Hmisc")
library(Hmisc)
var.labels = c(mpg="Miles/(US) gallon",
cyl="Number of cylinders",
disp="Displacement (cu.in.)",
hp="Gross horsepower",
drat="Rear axle ratio",
wt="Weight (1000 lbs)",
qsec="1/4 mile time",
vs="Engine (0 = V-shaped, 1 = straight)",
am="Transmission (0 = automatic, 1 = manual)",
gear="Number of forward gears",
carb="Number of carburetors")
label(dat01) <- as.list(var.labels[match(names(dat01), names(var.labels))])
Labels <- label(dat01)
Type <- c(mode(dat01$mpg),
mode(dat01$cyl),
mode(dat01$disp),
mode(dat01$hp),
mode(dat01$drat),
mode(dat01$wt),
mode(dat01$qsec),
mode(dat01$vs),
mode(dat01$am),
mode(dat01$gear),
mode(dat01$carb))
meta.df <- data.frame(Variables,
Type,
Labels)
print(meta.df, row.names = FALSE)
В дополнение к повышению эффективности моего скрипта (в частности, я уверен, что существует более эффективный код, который я могу использовать для создания векторного «Типа»), мне также интересно услышать ваши предложения о том, как лучше обобщить этот скрипт, чтобы его можно было копировать / вставлять и применять каналогично структурированные data.frames.
Комментарии:
1.
Type = sapply(mtcars, mode)
было бы довольно стандартным. Способ сделать его обобщаемым — поместить его в функцию, возможно, функцию данных, принимая пользовательские метки в качестве необязательного аргумента.2. Я бы также задался вопросом, уверены ли вы
mode
, что это нужная вам информация.class
это намного полезнее, но тогда вам нужно решить, что делать с многоклассовыми объектами. Но такие вещи, какmode(factor(1:3))
,mode(Sys.Date())
,mode(Sys.time())
— это всеnumeric
, что заставляет меня не любить mode .3. Я не уверен, что вы имеете в виду, когда говорите, что режим является числовым. Когда я использую mode (variable.name ), он возвращает символьную строку, указывающую тип элемента данных (например, «символьный», «числовой», «логический» и т.д.). Кажется, что класс (variable.name ) делает то же самое, за исключением того, что sapply(dat01, class) также возвращает строку, указывающую, что каждый столбец в моем фрейме данных «помечен».
4. Да,
mode
иclass
возвращать символьные строки.mode(Sys.Date())
возвращает символьную строку"numeric"
, поскольку даты хранятся внутри в виде чисел.class(Sys.Date())
возвращает символьную строку"Date"
. Я хочу сказать, чтоclass
возвращаемая информация более полезна, поскольку факторы, даты, временные метки и целые числа будут идентифицироватьсяmode
как простые"numeric"
, ноclass
будут различать их и обычные цифры. Информация, возвращаемаяclass
обычно, более полезна.5.
test_list = list(date = Sys.Date(), time = Sys.time(), factor = factor('a'), integer = 1L, numeric = 1.5)
. Сравнитеlapply(test_list, mode)
сlapply(test_list, class)
. Но здесь вы также можете видеть, чтоclass
необязательно возвращать строки длиной 1,class(Sys.time())
,class(factor('a', ordered = T))
— это два базовых примера с несколькими классами… что может усложнить задачу. Выборclass(x)[1]
был бы довольно хорошим значением по умолчанию.
Ответ №1:
Первым решением было бы дедуплицировать это Type
определение:
Поскольку class(some_vector)
возвращает единственную строку, описывающую тип данных в этом векторе, и поскольку фрейм данных представляет собой список векторов, вы можете использовать такой код:
Type <- unlist(Map(class, mtcars))
[однако вам может потребоваться изменить порядок записей]
Комментарии:
1.
class
не всегда возвращает одну строку. Попробуйтеclass(factor(1:3, ordered = TRUE))
илиclass(Sys.time())
для примеров многоклассовых объектов, которые часто отображаются в виде столбцов данных.2. прошу прощения, моя ошибка