【问题标题】:Print levels of a factor present within select criteria rather than all levels of the factor in R?打印选择标准中存在的因子的级别,而不是 R 中因子的所有级别?
【发布时间】:2025-12-26 13:25:10
【问题描述】:

我正在使用 R 版本 i386 3.1.1 和 RStudio 0.99.442。

我有从 7 个地块收集的大量树种数据集,每个地块又分为 5 个子地块(即 35 个不同的子地块)。我试图让 R 遍历我的数据集并打印每个地块中存在的物种。

我认为我可以使用“聚合”将“级别”函数应用于物种数据列并让它返回每个图和子图的物种,但是它返回整个数据框的级别(对于 12 个物种,总数)而不是子图中实际存在的 3 或 4 个物种。

为了提供我正在尝试做的可重现示例,我们可以使用 R 附带的“warpbreaks”数据集。

我将 warpbreaks 中的“breaks”变量转换为因子变量以重现问题;因此,它举例说明了我的“物种”变量,而“warpbreaks$wool”代表“情节”,“warpbreaks$tension”代表“子情节”。

require(stats)
warpbreaks$breaks = as.factor(warpbreaks$breaks)
aggregate(breaks ~ wool + tension, data = warpbreaks, FUN="levels")

如果我们查看 warpbreaks 数据,那么对于“Plot”A(羊毛)和“Subplot”L(张力) - 所需的脚本将打印物种“26、30、54、25 等”。

breaks wool tension
1      26    A       L
2      30    A       L
3      54    A       L
4      25    A       L
5      70    A       L
6      52    A       L
7      51    A       L
8      26    A       L
9      67    A       L
10     18    A       M
11     21    A       M
12     29    A       M
...

相反,R 返回这种类型的东西,它正在打印所有图的因子变量的所有水平:

    wool tension breaks.1 breaks.2 breaks.3 breaks.4 breaks.5 breaks... 
1    A       L       10       12       13       14       15       ...      
2    B       L       10       12       13       14       15       ...      
3    A       M       10       12       13       14       15       ...      
4    B       M       10       12       13       14       15       ...      
5    A       H       10       12       13       14       15       ...      
6    B       H       10       12       13       14       15       ...      

如何让它只打印该 Plot/Subplot 组合中存在的因素?我完全不使用“聚合”了吗?我想这对于经验丰富的 R 用户来说是一项相对容易的任务......

第一次发布 * 帖子 - 如有任何帮助或推动正确的代码,将不胜感激!

非常感谢。

【问题讨论】:

    标签: r


    【解决方案1】:

    尝试FUN=unique 而不是FUN=levelslevels 将返回因子的每个级别,正如您已经推测的那样。 unique(...) 只会返回唯一级别。

    y <- aggregate(breaks ~ wool + tension, data = warpbreaks, FUN=unique)
      wool tension                          breaks
    1    A       L  14, 18, 29, 13, 31, 28, 27, 30
    2    B       L    15, 4, 17, 9, 19, 23, 10, 26
    3    A       M     8, 11, 17, 7, 2, 20, 18, 21
    4    B       M    24, 14, 9, 6, 22, 16, 11, 17
    5    A       H 21, 11, 12, 8, 1, 25, 16, 5, 14
    6    B       H      10, 11, 12, 7, 3, 5, 6, 16
    

    注意breaks 列有点奇怪,因为在该列的每一行中,不是只有一个值(这对数据框有意义),而是一个值向量。即breaks 列的每个单元格都不是字符串;这是一个向量!

    > class(y$wool)
    [1] "factor"
    > class(y$breaks) # list !!
    [1] "list"
    > y$breaks[[1]] # first row in breaks
    [1] 26 30 54 25 70 52 51 67
    Levels: 10 12 13 14 15 16 17 18 19 20 21 24 25 26 27 28 29 30 31 35 36 39 41 42 43 44 51 52 54 67 70
    

    请注意,要访问breaks 列的第一个元素,而不是执行y$breaks[1](就像使用wooltension 列一样),因此您需要执行y$breaks[[1]]

    数据框并不是真的要像这样工作;数据帧中的单个单元格应该有一个值,并且大多数函数都希望数据帧符合这一点,因此在进行后续处理时请记住这一点。

    如果要转换为字符串,请使用(例如)FUN=function (x) paste(unique(x), collapse=', ');那么y$breaks 将是一列字符串并且表现正常。

    【讨论】:

    • 完美!谢谢 - 添加的信息非常有帮助。
    最近更新 更多