首页 > 解决方案 > 如何创建一个函数来计算单个单元中特定字符的共现次数?

问题描述

我正在尝试创建一个函数,使 R 能够读取每个单数单元(ID)并计算该单元中特定字符同时出现的次数。数据集如下:

       ID    class  weight
1       1       A       1.0
2       1       A       1.0
3       1       B       1.0
4       2       A       1.0
5       2       B       1.0
6       2       C       1.0
7       3       B       1.0
8       4       B       1.0
9       4       C       1.0
10      4       C       1.0
11      4       D       1.0
12      4       D       1.0
13      5       A       0.9
14      5       B       0.9
15      5       C       0.9
16      5       D       0.9
17      6       B       0.8
18      6       B       0.8
19      7       C       0.7
20      7       C       0.7
21      7       D       0.7
22      7       D       0.7
23      8       C       0.6
24      8       D       0.6
25      9       D       0.5
26      9       E       0.5
27      9       E       0.5
28     10       C       0.4
29     10       C       0.4
30     10       C       0.4
31     10       E       0.4
32     11       A       0.3
33     11       A       0.3
34     11       A       0.3
35     12       A       0.2
36     12       B       0.2
37     12       C       0.2
38     13       B       0.1
39     13       D       0.1
40     13       D       0.1
41     13       E       0.1
42     14       D       1.0
43     14       E       1.0
44     15       B       1.0
45     15       B       1.0
46     15       C       1.0
47     15       C       1.0
48     15       D       1.0
49     16       C       1.0
50     16       D       1.0
51     16       E       1.0
52     16       E       1.0
53     17       B       1.0
54     17       C       1.0
55     17       C       1.0
56     18       D       1.0
57     18       D       1.0
58     18       E       1.0
59     19       E       1.0
60     19       E       1.0
61     20       B       1.0
62     20       D       1.0
63     20       E       1.0
64     20       E       1.0

我试图创建一个循环函数,但我不知道如何正确指定表达式。R 应该识别从 1 到 20 的 ID,并在每个 ID 中计算字符同时出现的次数。不仅如此,每个共现都必须通过 ID 的特定权重来加权。关于生成循环函数的任何想法?

一些细节:在 ID 1 中,A 和 B 类共现两次(第一次 A 与 B,第二次 A 与 B),乘以权重 (1) 得出初步值 2。A 和 B 的共现值在循环完成整个列表后,B 应该是 4.1,并且该值应该在矩阵 5x5 中报告,如下所示:

   A   B    C    D    E
A  1   4.1  ..
B 4.1  1    ..
C ..   ..   1
D ..             1
E ..                  1

相同类之间的共现将仅为 1。

dput(数据)结构(列表(ID = c(1L,1L,1L,2L,2L,2L,3L,4L,4L,4L,4L,4L,5L,5L,5L,5L,6L,6L,7L, 7L, 7L, 7L, 8L, 8L, 9L, 9L, 9L, 10L, 10L, 10L, 10L, 11L, 11L, 11L, 12L, 12L, 12L, 13L, 13L, 13L, 13L, 14L, 14L, 15L, 15L, 15L, 15L, 15L, 16L, 16L, 16L, 16L, 17L, 17L, 17L, 18L, 18L, 18L, 19L, 19L, 20L, 20L, 20L, 20L), 等级 = c("A", " A”、“B”、“A”、“B”、“C”、“B”、“B”、“C”、“C”、“D”、“D”、“A”、“B” 、“C”、“D”、“B”、“B”、“C”、“C”、“D”、“D”、“C”、“D”、“D”、“E”、“ E”、“C”、“C”、“C”、“E”、“A”、“A”、“A”、“A”、“B”、“C”、“B”、“D”、“D”、“E”、“D”、“E”、“B”、“B” 、“C”、“C”、“D”、“C”、“D”、“E”、“E”、“B”、“C”、“C”、“D”、“D”、“ E”, “E”, “E”, “B”, “D”, “E”, “E”), 重量 = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.9, 0.9, 0.9, 0.9, 0.8, 0.8, 0.7, 0.7, 0.7, 0.7, 0.6, 0.6, 0.5, 0.5, 0.5, 0.4, 0.4, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.2, 0.2, 0.1, 0.1, 0.1, 0.1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)), row.names = c(NA, -64L), class = c("data.table", "data.帧"), .internal.selfref = ) gc() 已使用 (Mb) gc 触发器 (Mb) 已使用最大值 (Mb) Ncells 2672851 142.8 4316924 230.6 4316924 230.6 Vcells 5761794 44.0 12425324 94.8 29629603 226.1 库(data-table) fread("toy.csv") dput(data) structure(list(ID = c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 6L, 6L, 7L, 7L, 7L, 7L, 8L, 8L, 9L, 9L, 9L, 10L, 10L, 10L, 10L, 11L, 11L, 11L, 12L, 12L, 12L, 13L, 13L, 13L, 13L, 14L, 14L, 15L, 15L, 15L, 15L, 15L, 16L, 16L, 16L, 16L, 17L, 17L, 17L, 18L, 18L, 18L, 19L, 19L, 20L, 20L, 20L, 20L), 等级= c(“A”,“A”,“B”,“A”,“B”,“C”,“B”,“B”,“C”,“C”,“D”,“D” , "A", "B", "C"、“D”、“B”、“B”、“C”、“C”、“D”、“D”、“C”、“D”、“D”、“E”、“E”、“ C”、“C”、“C”、“E”、“A”、“A”、“A”、“A”、“B”、“C”、“B”、“D”、“D” 、“E”、“D”、“E”、“B”、“B”、“C”、“C”、“D”、“C”、“D”、“E”、“E”、“ B”、“C”、“C”、“D”、“D”、“E”、“E”、“E”、“B”、“D”、“E”、“E”),重量 = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.9, 0.9, 0.9, 0.9, 0.8, 0.8, 0.7, 0.7,0.7, 0.7, 0.6, 0.6, 0.5, 0.5, 0.5, 0.4, 0.4, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.2, 0.2, 0.1, 0.1, 0.1, 0.1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)), row.names = c(NA, -64L ), class = c("data.table", "data.frame"), .internal.selfref = )

标签: rfunction

解决方案


这是一种方法:

library(tidyverse)

数据

data <- structure(list(ID = c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 6L, 6L, 7L, 7L, 7L, 7L, 8L, 8L, 9L, 9L, 9L, 10L, 10L, 10L, 10L, 11L, 11L, 11L, 12L, 12L, 12L, 13L, 13L, 13L, 13L, 14L, 14L, 15L, 15L, 15L, 15L, 15L, 16L, 16L, 16L, 16L, 17L, 17L, 17L, 18L, 18L, 18L, 19L, 19L, 20L, 20L, 20L, 20L), class = c("A", "A", "B", "A", "B", "C", "B", "B", "C", "C", "D", "D", "A", "B", "C", "D", "B", "B", "C", "C", "D", "D", "C", "D", "D", "E", "E", "C", "C", "C", "E", "A", "A", "A", "A", "B", "C", "B", "D", "D", "E", "D", "E", "B", "B", "C", "C", "D", "C", "D", "E", "E", "B", "C", "C", "D", "D", "E", "E", "E", "B", "D", "E", "E"), weight = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.9, 0.9, 0.9, 0.9, 0.8, 0.8, 0.7, 0.7, 0.7, 0.7, 0.6, 0.6, 0.5, 0.5, 0.5, 0.4, 0.4, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.2, 0.2, 0.1, 0.1, 0.1, 0.1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)), row.names = c(NA, -64L), class = c("data.table", "data.frame")) %>% as_tibble()

主要的

创建一个“计数”数据框:

(df <- data %>%
  count(ID, class, weight) %>%
  spread(class, n, fill = 0))

获取类的所有组合:

eg <- expand.grid(unique(data$class), unique(data$class), stringsAsFactors = FALSE)

用对和加权计数制作一个小标题:

final <- map2(
  eg$Var1,
  eg$Var2,
  ~ df %>% select(.x, .y, weight) %>% 
    mutate(counts = !!sym(.x) * !!sym(.y)) %>%
    mutate(wt_counts = counts * weight) %>%
    select(wt_counts) %>%
    sum() %>%
    tibble(Var1 = .x, Var2 = .y, wt_count = .)
) 

转换为矩阵:

finalmatrix <- bind_rows(final) %>%
  mutate(wt_count = ifelse(Var1 == Var2, 1, wt_count)) %>%
  spread(Var2, wt_count) %>%
  select(-Var1) %>%
  as.matrix()

最后,设置名称:

row.names(finalmatrix) <- colnames(finalmatrix)

结果

> finalmatrix
    A    B    C    D   E
A 1.0  4.1  2.1  0.9 0.0
B 4.1  1.0 10.1  6.1 2.1
C 2.1 10.1  1.0 11.3 3.2
D 0.9  6.1 11.3  1.0 8.2
E 0.0  2.1  3.2  8.2 1.0

笔记

我个人不喜欢我的解决方案有多长,而且我看不到使用rlang东西(!!sym())的方法,但它仍然有效。


推荐阅读