R中数据帧中每行的唯一元素的计数

时间:2017-04-24 06:10:00

标签: r dataframe

我有一个如下数据框:

Group1  Group2  Group3  Group4
A       B       A       B   
A       C       B       A   
B       B       B       B   
A       C       B       D   
A       D       C       A   

我想在数据框中添加一个新列,每列中包含唯一元素的数量。期望的输出:

Group1  Group2  Group3  Group4  Count
A       B       A       B       2
A       C       B       A       3
B       B       B       B       1
A       C       B       D       4
A       D       C       A       3

我可以使用

为每一行找到这样的计数
length(unique(c(df[,c(1,2,3,4)][1,])))

我想对数据框中的所有行执行相同的操作。我尝试使用var = 1的apply()但没有成功。此外,如果您能为此提供更强大的优雅解决方案,那就太棒了。

3 个答案:

答案 0 :(得分:4)

我们可以使用applyMARGIN =1来循环遍历行

df1$Count <- apply(df1, 1, function(x) length(unique(x)))
df1$Count
#[1] 2 3 1 4 3

或使用tidyverse

library(dplyr)
df1 %>%
    rowwise() %>%
    do(data.frame(., Count = n_distinct(unlist(.))))
# A tibble: 5 × 5
#   Group1 Group2 Group3 Group4 Count
#*  <chr>  <chr>  <chr>  <chr> <int>
#1      A      B      A      B     2
#2      A      C      B      A     3
#3      B      B      B      B     1
#4      A      C      B      D     4
#5      A      D      C      A     3

我们也可以使用regex以更快的方式执行此操作。它基于每个单元格只有一个字符的假设

nchar(gsub("(.)(?=.*?\\1)", "", do.call(paste0, df1), perl = TRUE))
#[1] 2 3 1 4 3

更详细的说明是here

答案 1 :(得分:3)

基础R中的

duplicated

df$Count <- apply(df,1,function(x) sum(!duplicated(x)))

#  Group1 Group2 Group3 Group4 Count
#1      A      B      A      B     2
#2      A      C      B      A     3
#3      B      B      B      B     1
#4      A      C      B      D     4
#5      A      D      C      A     3

答案 2 :(得分:2)

虽然这里提到了一些非常棒的解决方案,但您也可以使用data.table

数据

df <- data.frame(g1 = c("A","A","B","A","A"),g2 = c("B", "C", "B","C","D"),g3 = c("A","B","B","B","C"),g4 = c("B","A","B","D","A"),stringsAsFactors = F)

<强>代码:

编辑:在David Arenberg的评论之后,添加(.I)而不是1:nrow(df)。感谢您的宝贵意见

library(data.table)
setDT(df)[, id := .I ]
df[, count := uniqueN(c(g1, g2, g3, g4)), by=id ]
df

<强>输出

> df
   g1 g2 g3 g4 id count
1:  A  B  A  B  1     2
2:  A  C  B  A  2     3
3:  B  B  B  B  3     1
4:  A  C  B  D  4     4
5:  A  D  C  A  5     3