r - 如何创建一个函数来计算单个单元中特定字符的共现次数?
问题描述
我正在尝试创建一个函数,使 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 = )
解决方案
这是一种方法:
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()
)的方法,但它仍然有效。
推荐阅读
- c - C中小数位的计算问题
- javascript - 如何从 nodejs 中的多步表单发布数据并表达到 MongoDB?
- python - Django ORM - 我可以使用 ID 以外的不同列创建具有外键的新对象吗?
- python - Python文件阅读:如何排除特定的子目录,反之亦然
- json - kotlinx.serialization:将 JSON 数组反序列化为密封类
- python - 为什么这两个列表推导会产生不同的结果?
- javascript - React Leaflet:地图调整点击/动态按钮的大小
- r - 从嵌套模式到 Excel 文件的数据框
- javascript - Bootstrap 进度条只触发到一半
- javascript - 未发送静态 css/图像文件 (NGINX/Express)