【问题标题】:r element frequency and column namer 元素频率和列名
【发布时间】:2015-03-26 22:45:30
【问题描述】:

我有一个包含四列 A、B、C 和 D 的数据框:

A    B    C    D
a    a    b    c
b    c    x    e
c    d    y    a
d              z
e
f

我想获取所有元素的频率和它们出现的列列表,按频率排名排序。输出将是这样的:

  Ranking  frequency column 
a    1         3      A, B, D
c    1         3      A, B, D
b    2         2      A, C
d    2         2      A, B
e    2         2      A, D
f  .....

如果有任何帮助,我将不胜感激。 谢谢!

【问题讨论】:

  • 请使用dput(dfrm)发布数据框。

标签: r frequency ranking frequency-distribution


【解决方案1】:

可能是这样的:

数据

df <- read.table(header=T, text='A    B    C    D
a    a    b    c
b    c    x    e
c    d    y    a
d   NA    NA     z
e  NA NA NA
f NA NA NA',stringsAsFactors=F)

解决方案

#find unique elements
elements <- unique(unlist(sapply(df, unique)))

#use a lapply to find the info you need
df2 <- data.frame(do.call(rbind,
        lapply(elements, function(x) {
          #find the rows and columns of the elements
          a <- which(df == x, arr.ind=TRUE)
          #find column names of the elements found
          b <- names(df[a[,2]])
          #find frequency
          c <- nrow(a)
          #produce output
          c(x, c, paste(b, collapse=','))
})))

#remove NAs
df2 <- na.omit(df2)
#change column names
colnames(df2) <- c('element','frequency', 'columns')
#order according to frequency
df2 <- df2[order(df2$frequency, decreasing=TRUE),]
#create the ranking column
df2$ranking <- as.numeric(factor(df2$frequency,levels=unique(df2$frequency)))

输出:

> df2
   element frequency columns ranking
1        a         3   A,B,D       1
3        c         3   A,B,D       1
2        b         2     A,C       2
4        d         2     A,B       2
5        e         2     A,D       2
6        f         1       A       3
8        x         1       C       3
9        y         1       C       3
10       z         1       D       3

如果您希望元素列作为 row.names 并且排名列在前,您也可以这样做:

row.names(df2) <- df2$element
df2$element <- NULL
df2 <- df2[c('ranking','frequency','columns')]

输出:

 > df2
  ranking frequency columns
a       1         3   A,B,D
c       1         3   A,B,D
b       2         2     A,C
d       2         2     A,B
e       2         2     A,D
f       3         1       A
x       3         1       C
y       3         1       C
z       3         1       D

【讨论】:

  • 不能再使用“加一”,但这是我的赞成票。在我的工作测试用例中没有成功,但可能会在提问者的结构上成功。
  • @BondedDust 感谢保税。我有一个小错误,它没有包含频率等于 1 的列的名称(现已修复),并且还包含了我的测试数据,因为我使用它来实现我的输出。
  • 这就是我看到这个奇怪物品的原因吧? 8 B,B.1,B.2,C,C.1,C.2,D,D.1,不,还在那里。我使用"" 作为空白空间。这就是我要求提供 dput 版本的原因。
  • @BondedDust 也许是的。不知道你用的是哪个测试用例,不过现在应该修好了。
  • 如果你使用“”作为一个项目,它会被算作一个独特的“元素”。
【解决方案2】:

这是一种使用“dplyr”和“tidyr”的方法:

library(dplyr)
library(tidyr)

df %>%
  gather(var, val, everything()) %>%             ## Make a long dataset
  na.omit %>%                                    ## We don't need the NA values
  group_by(val) %>%                              ## All calculations grouped by val
  summarise(column = toString(var),              ## This collapses
            freq = n()) %>%                      ## This counts
  mutate(ranking = dense_rank(desc(freq))) %>%   ## This ranks
  arrange(ranking)                               ## This sorts
# Source: local data frame [9 x 4]
# 
#   val  column freq ranking
# 1   a A, B, D    3       1
# 2   c A, B, D    3       1
# 3   b    A, C    2       2
# 4   d    A, B    2       2
# 5   e    A, D    2       2
# 6   f       A    1       3
# 7   x       C    1       3
# 8   y       C    1       3
# 9   z       D    1       3

【讨论】:

    猜你喜欢
    • 2021-08-19
    • 2017-09-29
    • 1970-01-01
    • 2018-03-23
    • 1970-01-01
    • 2015-03-14
    • 2013-05-09
    • 2021-02-09
    • 1970-01-01
    相关资源
    最近更新 更多