【问题标题】:Calculating frequency of values by column in R在R中按列计算值的频率
【发布时间】:2021-10-18 13:30:10
【问题描述】:

有谁知道如何将单元格的值替换为该值在列中出现的频率?我正在尝试将一个充满品种标签和基因因子的数据框转换为频率图(稍后会查看一个基因的共同等位基因的动物是否也倾向于具有其他基因的共同等位基因)。例如,我的初始数据框如下所示:

Breed    Gene A     Gene B    Gene C
Collie      3          5         8
Collie      5          7         2
Lab         3          3         1
Pug         3          7         8
Pug         3          7         9
Pug         4          4         9

我希望结果如下所示:

Breed    Gene A     Gene B    Gene C
2           4          1         2
2           1          3         1
1           4          1         1
3           4          3         1
3           4          3         2
3           1          1         2

我可以看到如何使用 for 循环来执行此操作(创建新的数据帧,遍历每一列,遍历每一行,将每个值更改为遇到相等值时加一的计数器),但是有更简单有效的 apply 或 dplyr 方法吗?数据集很大,我会经常重新运行,我担心嵌套的 for 循环会太慢。

【问题讨论】:

  • 要直观地检查数据,可以尝试绘制它:image(sapply(df, function(i) as.integer(as.factor(i))))

标签: r dplyr frequency


【解决方案1】:

这是一个基本的 R 选项 -

replace_value_by_count <- function(x) ave(x, x, FUN = length)
df[] <- lapply(df, replace_value_by_count)
df

#  Breed GeneA GeneB GeneC
#1     2     4     1     2
#2     2     1     3     1
#3     1     4     1     1
#4     3     4     3     2
#5     3     4     3     2
#6     3     1     1     2

既然你已经标记了dplyr,同样的功能也可以用dplyr来使用。

library(dplyr)
df <- df %>% mutate(across(.fns = replace_value_by_count))

数据

df <- structure(list(Breed = c("Collie", "Collie", "Lab", "Pug", "Pug", 
"Pug"), GeneA = c(3L, 5L, 3L, 3L, 3L, 4L), GeneB = c(5L, 7L, 
3L, 7L, 7L, 4L), GeneC = c(8L, 2L, 1L, 8L, 9L, 9L)), 
class = "data.frame", row.names = c(NA, -6L))

【讨论】:

    【解决方案2】:

    我们可能会使用base R

    df[] <- lapply(df, function(x) table(x)[as.character(x)])
    

    -输出

    > df
      Breed GeneA GeneB GeneC
    1     2     4     1     2
    2     2     1     3     1
    3     1     4     1     1
    4     3     4     3     2
    5     3     4     3     2
    6     3     1     1     2
    

    或者使用tidyverse

    library(dplyr)
    df %>%
        mutate(across(everything(), ~ tibble(col1 = .x) %>% 
                 add_count(col1) %>% 
                 pull(n)))
      Breed GeneA GeneB GeneC
    1     2     4     1     2
    2     2     1     3     1
    3     1     4     1     1
    4     3     4     3     2
    5     3     4     3     2
    6     3     1     1     2
    

    数据

    df <- structure(list(Breed = c("Collie", "Collie", "Lab", "Pug", "Pug", 
    "Pug"), GeneA = c(3L, 5L, 3L, 3L, 3L, 4L), GeneB = c(5L, 7L, 
    3L, 7L, 7L, 4L), GeneC = c(8L, 2L, 1L, 8L, 9L, 9L)),
       class = "data.frame", row.names = c(NA, 
    -6L))
    

    【讨论】:

      猜你喜欢
      • 2019-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-12
      • 1970-01-01
      • 2013-12-28
      相关资源
      最近更新 更多