【问题标题】:Calculate product of frequencies in each column计算每列频率的乘积
【发布时间】:2018-10-10 04:33:21
【问题描述】:

我有一个包含 3 列的数据框,每列包含少量值:

> df
# A tibble: 364 x 3
   A     B     C
 <dbl> <dbl> <dbl>
  0.    1. 0.100
  0.    1. 0.200
  0.    1. 0.300
  0.    1. 0.500
  0.    2. 0.100
  0.    2. 0.200
  0.    2. 0.300
  0.    2. 0.600
  0.    3. 0.100
  0.    3. 0.200
# ... with 354 more rows



> apply(df, 2, table)
$`A`

 0  1  2  3  4  5  6  7  8  9 10 
34 37 31 32 27 39 29 28 37 39 31 

$B

 1  2  3  4  5  6  7  8  9 10 11 
38 28 38 37 32 34 29 33 30 35 30 

$C

0.1 0.2 0.3 0.4 0.5 0.6 
 62  65  65  56  60  56 

我想创建第四列,其中将包含每一行每个值与每个组的频率的乘积。因此,例如,“Freq”列的第一个值将是 A 列中 0 的频率、B 列中 1 的频率和 C 列中 0.1 的频率的乘积。

如何使用 dplyr/baseR 有效地做到这一点?

要强调的是,这不是每行总频率的组合,而是 1 列频率的乘积

【问题讨论】:

  • 最后一行呢? A 列有 11 个元素,B 列也有 11 个元素,而 C 列有 6 个元素。那么你该怎么做呢?

标签: r count dplyr summarize


【解决方案1】:

使用来自基础 R 的 lapplyMapReduce 组合的有效方法:

l <- lapply(df, table)

m <- Map(function(x,y) unname(y[match(x, names(y))]), df, l)

df$D <- Reduce(`*`, m)

给出:

> head(df, 15)
    A  B   C     D
1   3  5 0.4 57344
2   5  6 0.5 79560
3   0  4 0.1 77996
4   2  6 0.1 65348
5   5 11 0.6 65520
6   3  8 0.5 63360
7   6  6 0.2 64090
8   1  9 0.4 62160
9  10  2 0.2 56420
10  5  2 0.2 70980
11  4 11 0.3 52650
12  7  6 0.5 57120
13 10  1 0.2 76570
14  7 10 0.5 58800
15  8 10 0.3 84175

这是做什么的:

  • lapply(df, table) 为每一列创建频率列表
  • 使用Map 创建一个使用match 的列表,其中每个列表项的长度与df 的行数相同。每个列表项都是与df 中的值相对应的频率向量。
  • 使用Reduce,列表m 中向量的乘积是按元素计算的:列表m 中每个向量的第一个值相互相乘,然后是第二个值,等等。李>

tidyverse中的方法相同:

library(dplyr)
library(purrr)

df %>% 
  mutate(D = map(df, table) %>% 
           map2(df, ., function(x,y) unname(y[match(x, names(y))])) %>% 
           reduce(`*`))

使用过的数据:

set.seed(2018)
df <- data.frame(A = sample(rep(0:10, c(34,37,31,32,27,39,29,28,37,39,31)), 364),
                 B = sample(rep(1:11, c(38,28,38,37,32,34,29,33,30,35,30)), 364),
                 C = sample(rep(seq(0.1,0.6,0.1), c(62,65,65,56,60,56)), 364))

【讨论】:

    【解决方案2】:

    将使用下面的小例子

    df
     A  B   C
    1   3  5 0.4
    2   5  6 0.5
    3   0  4 0.1
    4   2  6 0.1
    5   5 11 0.6
    6   3  8 0.5
    7   6  6 0.2
    8   1  9 0.4
    9  10  2 0.2
    10  5  2 0.2
    sapply(g,table)
    $A
    
     0  1  2  3  5  6 10 
     1  1  1  2  3  1  1 
    
    $B
    
     2  4  5  6  8  9 11 
     2  1  1  3  1  1  1 
    
    $C
    
    0.1 0.2 0.4 0.5 0.6 
      2   3   2   2   1 
    
    
    library(tidyverse)
    df%>%
      group_by(A)%>%
      mutate(An=n())%>%
      group_by(B)%>%
      mutate(Bn=n())%>%
      group_by(C)%>%
      mutate(Cn=n(),prod=An*Bn*Cn)
    
    
    
           A     B     C    An    Bn    Cn  prod
       <int> <int> <dbl> <int> <int> <int> <int>
     1     3     5 0.400     2     1     2     4
     2     5     6 0.500     3     3     2    18
     3     0     4 0.100     1     1     2     2
     4     2     6 0.100     1     3     2     6
     5     5    11 0.600     3     1     1     3
     6     3     8 0.500     2     1     2     4
     7     6     6 0.200     1     3     3     9
     8     1     9 0.400     1     1     2     2
     9    10     2 0.200     1     2     3     6
    10     5     2 0.200     3     2     3    18
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-11
      • 2021-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多