【问题标题】:R dataframe to "dictionary" avoiding list of factorsR数据框到“字典”避免因素列表
【发布时间】:2018-09-27 18:10:34
【问题描述】:

我有一个数据框 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。这几乎是我想要的,因为 $ 运算符工作正常。但是,我真的不习惯使用因子,我想知道是否还有另一个 dataframe-to-list 转换可用。烦人的部分来自于这样一个事实:为了处理字符串和数字,我们必须将 factors 转换回这些类型

> 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"

但我有同样的结果。

有人有建议吗?我错过了什么明显的东西吗?

坦克:)

【问题讨论】:

    标签: r list dictionary hash r-factor


    【解决方案1】:

    我们可以通过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)
    

    【讨论】:

    • 非常整洁,不知道这个purrr 包,但它满足我的需要,非常感谢!
    【解决方案2】:

    基于 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)
    

    【讨论】:

    • 谢谢,但是例如当我将数字更改为负整数或大于 10 的数字甚至浮点数时,它似乎不起作用...:/
    猜你喜欢
    • 1970-01-01
    • 2021-04-10
    • 2020-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-28
    • 2017-10-19
    相关资源
    最近更新 更多