根据一列的值,汇总多列中的唯一值

5

我希望根据var_1的值,了解每列唯一值的总数。

例如:

Test <- data.frame(var_1 = c("a","a","a", "b", "b", "c", "c", "c", "c", "c"), var_2 = c("bl","bf","bl", "bl","bf","bl","bl","bf","bc", "bg" ), var_3 = c("cf","cf","eg", "cf","cf","eg","cf","dr","eg","fg"))

我将根据 var_1 中的值翻译以下内容:

我正在寻找的结果应该基于 var_1 中的值,并且应为:

var_1 var_2 var_3
a     2     2
b     2     1
c     3     4

然而,经过尝试各种方法(包括apply和table)- aggregate是我所寻找的最接近的东西,但是这个脚本的结果是每个var_1值的条目总数的摘要,但总数不是唯一的。

agbyv1= aggregate(. ~ var_1, Test, length) 

var_1 var_2 var_3
a     3     3
b     2     2
c     5     5

我试过了

unqbyv1= aggregate(. ~ var_1, Test, length(unique(x)))

但是那并没有起作用。

非常感谢任何帮助。


你的第二个“aggregate”方法几乎是正确的! - talat
2个回答

7

尝试

library(dplyr)
Test %>%
      group_by(var_1) %>% 
      summarise_each(funs(n_distinct(.)))

或者

library(data.table)#v1.9.5+
setDT(Test)[, lapply(.SD, uniqueN), var_1]

如果存在NA值
setDT(Test)[, lapply(.SD, function(x) uniqueN(na.omit(x))), var_1]

或者您可以使用aggregate。默认情况下,na.action=na.omit。因此,我们不需要进行任何修改。

aggregate(.~ var_1, Test, FUN=function(x) length(unique(x)) )

刚刚注意到NA值没有被省略,我该如何将这段脚本添加进去?我尝试在开头添加na.omit() %>%,但是不起作用。 - Ina.Quest
在我的大型数据集中,我注意到使用这个脚本时NA值没有被省略。我尝试在开头添加na.omit() %>%,但是这样做不正确,因为它会删除所有带有na值的行,而不是在计算每列时忽略它们。 - Ina.Quest
谢谢你的额外帮助,但对于具有NA值的较大数据集仍然不正确。上面的聚合行删除了所有NA行,因此我得到了每列缩写的唯一计数。我只想让它不计算NA,而是计算每列中其余唯一条目的数量。 - Ina.Quest
短期考虑:uniqueN不在CRAN的data.table包中,但是function(x)length(unique(x))可以代替它。 - Frank
1
@Ina.Quest 我猜na.omit应该放在each列操作附近,像n_distinct(na.omit(.)) - Frank
显示剩余5条评论

0

试试这个:

apply(Test[-1] , 2 , function(y) tapply(y,Test$var_1,function(x) length(unique(x))))

谢谢,它适用于上面的虚拟数据,但对于我的更大数据集,我遇到了一个错误:Error in tapply(y, oh$RM, function(x) length(unique(x))) : arguments must have same length... 你知道这是什么意思吗? - Ina.Quest
如果您输入的列名错误,@Ina.Quest oh$RM 将会长度为零。 - Frank
@Erin - 我尝试了:apply(oh[-1], 2, function(y) tapply(y,oh$RM,function(x) length(unique(x)))) - 这里的oh是我的数据集,RM是我想要排序的列。当我运行脚本时,我得到了我上面发布的错误。 - Ina.Quest
没有查看您的实际数据集,很难确定问题所在。 - Eric Brooks

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