未分割列表、合并因素

4

I have the following data frame in R:

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

然后我按以下方式进行splitz = 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]    

在我的实际数据框中,我有一个非常大的列表,因此我需要迭代所有列表元素(不仅仅是两个)。做到这一点最好的方法是什么?

2个回答

4
你能不能直接使用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 - Alex
@Alex,你之前并没有明确表示你想把这个结果放回原始数据中。我更新了我的答案,大大简化了整个过程——只需一行代码即可完成你想要的所有操作,无需额外的包等。 - Gavin Simpson
1
我稍微偏爱(test2 <- transform(test, newvar = unlist(lapply(split(c1, c2), cut, 2)))) [但你的代码更短一些] - Ben Bolker
我有一个问题想问大家:我想聚合这些因子,以便使用 cut 切分成的两个桶可以得到相同的处理。 目前,cut 为每个日期生成两个不同的间隔。 我希望它为每个日期生成两个“桶”,无论日期如何都可以得到相同的处理。 有什么好办法可以做到这一点吗? 我尝试过使用 function(x) {z <- cut(x,2); levels(z)<-c("bucket1", "bucket2")} 而不是使用 cut,但似乎不起作用。 谢谢! - Alex
看起来在 cut 函数中使用标签可以让我做到这一点。 - Alex

4
如果我正确理解了你的问题,那么我认为你把问题想得太复杂了。这里提供一种使用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

是的,这正是我想做的。非常感谢你的帮助!-Alex - Alex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接