gpt4 book ai didi

r - 计算两个值在 R 中的一个组内同时出现的次数

转载 作者:行者123 更新时间:2023-12-05 04:58:22 26 4
gpt4 key购买 nike

我搜索了这个问题的答案并找到了类似的答案(Count number of rows within each groupcount unique combinations of variable values in an R dataframe columnR count occurrences of an element by groups),但没有一个能解决我的特定问题。

我有一个包含变量 yearIDcode 的数据框。每个人都有一个 ID,并且在(可能)多年 的过程中可以有多个 code 值。

df = data.frame(ID   = c(1,1,1,1, 2,2,2, 3, 4,4,4,4,4,4,4,4, 5,5,5),
year = c(2018, 2018, 2020, 2020,
2020, 2020, 2020,
2011,
2019, 2019, 2019, 2019, 2020, 2020, 2020, 2020,
2018, 2019, 2020),
code = c("A", "B", "C", "D",
"A", "B", "Q",
"G",
"A", "B", "Q", "G", "C", "D", "T", "S",
"S", "Z", "F")

)

df
ID year code
1 1 2018 A
2 1 2018 B
3 1 2020 C
4 1 2020 D
5 2 2020 A
6 2 2020 B
7 2 2020 Q
8 3 2011 G
9 4 2019 A
10 4 2019 B
11 4 2019 Q
12 4 2019 G
13 4 2020 C
14 4 2020 D
15 4 2020 T
16 4 2020 S
17 5 2018 S
18 5 2019 Z
19 5 2020 F

我想要的是另一个数据框,给出 code 的两个不同值在 IDyear 的分组中同时出现的次数>(在本例中,A 和 B 共现 3 次,A 和 C 共现 0 次),然后我将使用它进行网络分析。

到目前为止我有这样的语法:

1:制作宽版数据

library(tidyverse)
wide = df %>%
group_by(year, ID) %>%
mutate(row = row_number()) %>%
ungroup() %>%
pivot_wider(
id_cols = c(ID, year),
names_from = row,
names_prefix = "code_",
values_from = code
)

2:制作节点列表

nodes = distinct(df, code) %>% rowid_to_column("id")

3:制作边列表

#edge list needs to be three vars: source, dest, and weight
# source and dest are simply code names that (potentially) co-occur in the same year for an ID
# weight is the number of times the codes co-occurred in the same year for each ID.

#all combinations of two codes
edges = combn(x = nodes$code, m = 2 ) %>%
t() %>%
as.data.frame()

colnames(edges) = c("source", "dest")
edges$weight = NA_integer_


#oh, no! a for() loop! a coder's last ditch effort to make something work
for(i in 1:nrow(edges)){

source = edges$source[i]
dest = edges$dest[i]


#get the cases with the first code of interest
temp = df %>%
filter( code == source ) %>%
select(ID, year)

#get the other codes that occurred for that ID in that year
temp = left_join(temp,
wide,
by = c("ID", "year"))


#convert to a logical showing if the other codes are the one I want
temp = temp %>% mutate_at(vars(starts_with("code_")),
function(x){ x == dest }
)

#sum the number of times `source` and `dest` co-occurred
temp$dest = temp %>% select(starts_with("code_")) %>% rowSums(., na.rm=TRUE)
edges$weight[i] = sum(temp$dest, na.rm = TRUE)

}

编辑添加结果:

结果:

edges
source dest weight
1 A B 3
2 A C 0
3 A D 0
4 A Q 2
5 A G 1
6 A T 0
7 A S 0
8 A Z 0
9 A F 0
10 B C 0
11 B D 0
12 B Q 2
13 B G 1
14 B T 0
15 B S 0
16 B Z 0
17 B F 0
18 C D 2
19 C Q 0
20 C G 0
21 C T 1
22 C S 1
23 C Z 0
24 C F 0
25 D Q 0
26 D G 0
27 D T 1
28 D S 1
29 D Z 0
30 D F 0
31 Q G 1
32 Q T 0
33 Q S 0
34 Q Z 0
35 Q F 0
36 G T 0
37 G S 0
38 G Z 0
39 G F 0
40 T S 1
41 T Z 0
42 T F 0
43 S Z 0
44 S F 0
45 Z F 0

这给了我想要的(一个数据帧显示 A 和 B 共同出现 3 次,A 和 C 共同出现 0 次,A 和 D 共同出现 0 次,A 和 G 共同出现 1 次,A和 Q 共同出现 2 次,等等......)。所以这是有效的,但即使是这个小例子也需要一两秒钟。我的真实数据集是 ~3,000,000 个观察值。我让它运行了一段时间,但停止运行后才发现它已完成约 1%。

有更好/更快的方法吗?

最佳答案

这里有一个替代方案,它只执行连接,因此对于大数据来说可能非常快。

library(data.table)
setDT(df)
df[df, on = c('ID','year'), allow.cartesian = TRUE][
code<i.code, .N, .(pair = paste0(code, i.code))]

#> pair N
#> 1: AB 3
#> 2: CD 2
#> 3: AQ 2
#> 4: BQ 2
#> 5: GQ 1
#> 6: AG 1
#> 7: BG 1
#> 8: CT 1
#> 9: DT 1
#> 10: ST 1
#> 11: CS 1
#> 12: DS 1

关于r - 计算两个值在 R 中的一个组内同时出现的次数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64034719/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com