如何在数据框中检索出现最频繁的列值

17

我想要获取数据框中特定列中出现最多的值。以下是我的示例数据和代码。

data("Forbes2000", package = "HSAUR")
head(Forbes2000)


  rank                name        country             category  sales profits  assets marketvalue
1    1           Citigroup  United States              Banking  94.71   17.85 1264.03      255.30
2    2    General Electric  United States        Conglomerates 134.19   15.59  626.93      328.54
3    3 American Intl Group  United States            Insurance  76.66    6.46  647.66      194.87
4    4          ExxonMobil  United States Oil & gas operations 222.88   20.96  166.99      277.02
5    5                  BP United Kingdom Oil & gas operations 232.57   10.27  177.57      173.54
6    6     Bank of America  United States              Banking  49.01   10.81  736.45      117.55
根据我的样本数据,我需要返回最常重复的类别,即保险。
subset(subset(Forbes2000,country=="Bermuda")

如何使用 sort(table(yourdata$category), decreasing=TRUE)[1]。当然还有很多其他方法! - Justin
我需要从我的数据中返回最常重复的值... - Teja
2
我认为这可以留给读者作为练习。names(sort(table(yourdata$category), decreasing=TRUE)[1]) 。但是,Josh在下面提出了一个很好的观点,如果你有并列呢! - Justin
9个回答

21
tail(names(sort(table(Forbes2000$category))), 1)

12

如果有两个或更多类别的频率相同,则可以使用以下方法:

x <- c("Insurance", "Insurance", "Capital Goods", "Food markets", "Food markets")
tt <- table(x)
names(tt[tt==max(tt)])
[1] "Food markets" "Insurance" 

5

使用data.table包的另一种方法,对于大型数据集来说更快:

set.seed(1)
x=sample(seq(1,100), 5000000, replace = TRUE)

方法一(上述提出的解决方案)

该方法是解决IT技术问题的一种方案。
start.time <- Sys.time()
tt <- table(x)
names(tt[tt==max(tt)])
end.time <- Sys.time()
time.taken <- end.time - start.time
time.taken

时间差为4.883488秒

方法2 (数据表格)

start.time <- Sys.time()
ds <- data.table( x )
setkey(ds, x)
sorted <- ds[,.N,by=list(x)]

most_repeated_value <- sorted[order(-N)]$x[1]
most_repeated_value

end.time <- Sys.time()
time.taken <- end.time - start.time
time.taken

时间差为0.328033秒


7
图森市,不错。我认为 as.data.table(ds)[, .N, by=x][, x[N == max(N)]] 也可以完成任务,在我的笔记本电脑上只需要0.06秒。供您参考,聚合操作不需要使用 setkey - Arun
@Arun 谢谢。你的解决方案应该在这个页面的顶部。 - Timothée HENRY

1
使用@Malvika的函数选项可以轻松地应用于整个表格,并获取每列的这些值。
#create a mode function
get_mode_name <- function(x){
  return(names(sort(table(x), decreasing = T, na.last = T)[1]))
}

get_mode_value <- function(x){
  return(unname(sort(table(x), decreasing = T, na.last = T)[1]))
}

get_mode_pct<- function(x){
  return(unname(sort(table(x), decreasing = T, na.last = T)[1])/length(x))
}

#Identify character columns
type_table <- sapply(table_name, class)

#create vector numeric and character types
num_table <- (unname(type_table) == "numeric")
char_table <- (unname(type_table) == "character")

#View the modes of character columns
mode_name <- apply(table_name[,char_table], 2, function(x) get_mode_name(x))    
mode_value <- apply(table_name[,char_table], 2, function(x) get_mode_value(x))
mode_pct <- apply(table_name[,char_table], 2, function(x) get_mode_pct(x))

1
以下是我最容易阅读和记住的内容:
names(which.max(table(Forbes2000$category)))

关于效率的额外说明:这种方法避免了对表格条目进行排序(找到最大值比完全排序要便宜)。最高效的解决方案将避免完全制表。你可以想象一个Rcpp解决方案,通过循环遍历源向量并保持一个运行制表,但在比赛结束之前停止。如果有人写出这个解决方案,请告诉我,我会给你一个+1,并编辑这个答案引用你的答案。

1

我知道我的回答有点晚,但我建立了以下函数,可以在不到一秒的时间内处理包含超过50,000行的数据框:

print_count_of_unique_values <- function(df, column_name, remove_items_with_freq_equal_or_lower_than = 0, return_df = F, 
                                         sort_desc = T, return_most_frequent_value = F)
{
  temp <- df[column_name]
  output <- as.data.frame(table(temp))
  names(output) <- c("Item","Frequency")
  output_df <- output[  output[[2]] > remove_items_with_freq_equal_or_lower_than,  ]

  if (sort_desc){
    output_df <- output_df[order(output_df[[2]], decreasing = T), ]
  }

  cat("\nThis is the (head) count of the unique values in dataframe column '", column_name,"':\n")
  print(head(output_df))

  if (return_df){
    return(output_df)
  }

  if (return_most_frequent_value){
      output_df$Item <- as.character(output_df$Item)
      output_df$Frequency <- as.numeric(output_df$Frequency)
      most_freq_item <- output_df[1, "Item"]
      cat("\nReturning most frequent item: ", most_freq_item)
      return(most_freq_item)
  }
}

如果您有一个名为“df”的数据框,其中包含一个名为“name”的列,并且您想知道“name”列中最常见的值,您可以运行:

most_common_name <- print_count_of_unique_values(df=df, column_name = "name", return_most_frequent_value = T)    

1
你可以创建一个函数:
get_mode <- function(x){
  return(names(sort(table(x), decreasing = T, na.last = T)[1]))
}

然后执行。
get_mode(Forbes3000$category)

我创建一个函数的原因是我经常需要做这种事情。

我喜欢这个解决方案,它使得在数据框中应用变得容易,并且可以快速地计算所有值。 - Tyler Knight

0

我建议使用Rfast::Table

Rfast::Table(as.character(Forbes2000$CategoryName))

你可以获得最大值。


0
你可以使用 table(Forbes2000$CategoryName, useNA="ifany")。这将为您提供所选类别中所有可能值的列表以及每个值在该特定数据框中使用的次数。

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