R dataframe в "словарь", избегая списка факторов
У меня есть датафрейм df
с двумя столбцами, один из которых содержит имена, а второй - значения, которые могут быть, например, строковыми или двойными
> df
name value
1 cat_name Bart
2 cat_age 5
3 dog_name Fred
4 dog_age 9
5 total_pet 2
Я хотел бы конвертировать
df
вlist
именованных объектов, чтобы я мог позвонитьlist$cat_name
и верни строку"Bart"
или жеlist$bird_age
и вернуться1
как числовой
я пробовал
> list <- split(df[, 2], df[, 1])
> list
$cat_age
[1] 5
Levels: 2 5 9 Bart Fred
$cat_name
[1] Bart
Levels: 2 5 9 Bart Fred
$dog_age
[1] 9
Levels: 2 5 9 Bart Fred
$dog_name
[1] Fred
Levels: 2 5 9 Bart Fred
$total_pet
[1] 2
Levels: 2 5 9 Bart Fred
который превращает df
в list
факторов. Это почти то, что я хочу, потому что $
Оператор работает нормально. Тем не менее, я не привык работать с факторами, и я хотел бы знать, было ли еще какое -то преобразование данных из списка в список доступных. Раздражающая часть происходит из-за того, что для работы со строками и числами мы должны преобразовать факторы обратно в эти типы
> as.character(list$cat_name)
[1] "Bart"
> as.numeric(as.character(list$total_pet))
[1] 3
Заметив это df[, 1]
а также df[, 2]
на самом деле факторы, которые я пытался использовать
> list <- split(as.character(df[, 2]), df[, 1])
> list
$cat_age
[1] "5"
$cat_name
[1] "Bart"
$dog_age
[1] "9"
$dog_name
[1] "Fred"
$total_pet
[1] "2"
что почти решает проблему, за исключением того, что числа являются символами, которые будут преобразованы позже. Я также пытался использовать hash
объекты
> h <- hash(as.vector(df[, 1]), as.vector(df[, 2]))
> l = as.list(h)
> l
$dog_age
[1] "9"
$dog_name
[1] "Fred"
$cat_age
[1] "5"
$total_pet
[1] "2"
$cat_name
[1] "Bart"
но у меня такой же результат.
У кого-нибудь есть совет? Я что-то упускаю из виду?
Танки:)
2 ответа
Мы можем сделать это с type.convert
library(purrr)
map(list, type.convert, as.is = TRUE)
#$cat_age
#[1] 5
#$cat_name
#[1] "Bart"
#$dog_age
#[1] 9
#$dog_name
#[1] "Fred"
#$total_pet
#[1] 2
Поскольку это может быть более эффективным путем параллельной реализации, один из вариантов future_map
от furrr
library(furrr)
plan(multiprocess)
future_map(list, type.convert, as.is = TRUE)
Базовый подход R...
df[,]<- lapply(df, as.character) # changing factors to character
list <- split(df[, 2], df[, 1]) # Split df just as you did.
list2 <- lapply(list, function(x) {
y <- regmatches(x, regexpr("\\d", x));
z <-ifelse(length(y)!=0, as.numeric(y), x);
z
})
$cat_age
[1] 5
$cat_name
[1] "Bart"
$dog_age
[1] 9
$dog_name
[1] "Fred"
$total_pet
[1] 2
Проверка класса:
> sapply(list2, class)
cat_age cat_name dog_age dog_name total_pet
"numeric" "character" "numeric" "character" "numeric"
Ваши данные:
df <- read.table(text=" name value
1 cat_name Bart
2 cat_age 5
3 dog_name Fred
4 dog_age 9
5 total_pet 2", header=TRUE)