【问题标题】:unsplit list, merge factors未拆分列表,合并因素
【发布时间】:2011-04-29 18:44:51
【问题描述】:

我在 R 中有以下数据框:

  c1 c2  
1 10  a  
2 20  a  
3 30  b  
4 40  b

我然后split它如下:z = lapply(split(test$c1, test$c2), function(x) {cut(x,2)}) z 则为:

$a  
[1] (9.99,15] (15,20]  
Levels: (9.99,15] (15,20]

$b  
[1] (30,35] (35,40]
Levels: (30,35] (35,40]  

然后我想通过取消拆分列表unsplit(z, test$c2) 来合并这些因素。这会产生一个警告:

[1] (9.99,15] (15,20]   <NA>      <NA>     
Levels: (9.99,15] (15,20]
Warning message:
In `[<-.factor`(`*tmp*`, i, value = 1:2) :
  invalid factor level, NAs generated

我想取所有因子水平的并集,然后取消拆分,以免发生此错误:

z$a = factor(z$a, levels=c(levels(z$a), levels(z$b)))
unsplit(z, test$c2)
[1] (9.99,15] (15,20]   (30,35]   (35,40]  
Levels: (9.99,15] (15,20] (30,35] (35,40]    

在我的真实数据框中,我有一个非常大的列表,因此我需要遍历所有列表元素(不仅仅是两个)。最好的方法是什么?

【问题讨论】:

    标签: r merge split interaction r-factor


    【解决方案1】:

    如果我正确理解了您的问题,我认为您使这比需要的要复杂一些。这是使用plyr 的一种解决方案。我们将按c2 变量分组:

    require(plyr)
    ddply(test, "c2", transform, newvar = cut(c1, 2))
    

    返回:

      c1 c2    newvar
    1 10  a (9.99,15]
    2 20  a   (15,20]
    3 30  b   (30,35]
    4 40  b   (35,40]
    

    结构如下:

    'data.frame':   4 obs. of  3 variables:
     $ c1    : num  10 20 30 40
     $ c2    : Factor w/ 2 levels "a","b": 1 1 2 2
     $ newvar: Factor w/ 4 levels "(9.99,15]","(15,20]",..: 1 2 3 4
    

    【讨论】:

    • 是的,这正是我想要做的。非常感谢你的帮助! -亚历克斯
    【解决方案2】:

    你能不能只用unlist() z 代替?

    > unlist(z)
           a1        a2        b1        b2 
    (9.99,15]   (15,20]   (30,35]   (35,40] 
    Levels: (9.99,15] (15,20] (30,35] (35,40]
    

    或者没有结果因子上的名称:

    > unlist(z, use.names=FALSE)
    [1] (9.99,15] (15,20]   (30,35]   (35,40]  
    Levels: (9.99,15] (15,20] (30,35] (35,40]
    

    您可以将所有内容合并成一个不需要附加包的简单单行:

    > (test2 <- within(test, newvar <- unlist(lapply(split(c1, c2), cut, 2))))
      c1 c2    newvar
    1 10  a (9.99,15]
    2 20  a   (15,20]
    3 30  b   (30,35]
    4 40  b   (35,40]
    

    【讨论】:

    • 我认为下面的答案使我的代码非常简单。你的效果也很好,但我只需要将它添加到数据框中。谢谢你的帮助! -亚历克斯
    • @Alex 不清楚您是否要将其粘贴回原始数据中。我已经更新了我的答案以极大地简化整个过程 - 1 行代码可以完成您想要的一切,而无需额外的软件包等。
    • 我对@9​​87654326@ 有一点偏爱[但你的要少几个字符]
    • 我有一个问题要问你们:我想汇总这些因素,以便我使用 cut 将事物分成的两个桶得到相同的处理。目前,cut 为每个日期生成两个不同的间隔。我希望它为每个日期生成两个“桶”,无论它是什么日期,它们都被视为相同。有什么好方法可以做到这一点?我尝试使用 cut 而不是使用:function(x) {z &lt;- cut(x,2); levels(z)&lt;-c("bucket1", "bucket2")} 但这似乎不起作用。谢谢!
    • 看起来剪切功能中的标签可以让我这样做。
    猜你喜欢
    • 1970-01-01
    • 2017-04-22
    • 1970-01-01
    • 2018-09-07
    • 2012-09-25
    • 2018-09-29
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    相关资源
    最近更新 更多