将因素出现的数据重构为基于共现的网络分析数据

问题描述 投票:0回答:1

我正在尝试根据某些因素的共现来重组我的数据(目的是使用节点和边进行网络分析)。在我的数据集中,每当具有 ID 的患者出现这些因素时,我的值就是“1”。

下面的数据框只是一个示例,而不是实际的数据集。实际数据集有更多变量和更多观察结果。

我正在尝试生成一个具有不同数据结构的数据集,当两个因素共存时,例如当 John 同时具有 bmi_100=1 和 crp_100=1 时,该数据集为我提供 ID 值。

在提供的演示数据中,您可以看到 John 和 Jeff 都有 bmi_100=1 和 crp_100=1。因此,在新数据集中,我想要一个变量“bmi_100.crp_100”,它具有观察值“John”和“Jeff”(即基于前一个数据集中的两个变量名称的变量名称以及它们之间的“.”分隔符) )。每个变量名称应由原始数据中的变量与分隔符的组合组成。新数据集中的变量应包括原始数据集中变量的所有可能组合。

下面我制作了现有数据结构的演示,下面是我尝试实现的新结构:

# What I have: unique IDs and occurrences for each variable
id <- c("John", "Cindy", "Laura", "Jeff", "Amy")
bmi_100  <- c(1, 1, 1, 1, 0)
crp_100  <- c(1, 0, 0, 1, 1)
eur <-      c(1, 0, 1, 1, 1)
cdai_rem <- c(1, 1, 0, 1, 0)
df1 <- data.frame(id, bmi_100, crp_100, eur, cdai_rem)
print(df1)

# What I try to get: for each co-occurrence put ID if co-occurrence and the rest of the observations put "0" to allow merging into dataframe)
bmi_100.crp_100  <- c("John", "Jeff", 0, 0, 0)
bmi_100.eur      <- c("John", "Laura", "Jeff", 0, 0)
bmi_100.cdai_rem <- c("John", "Cindy", "Jeff", 0, 0)
crp_100.eur      <- c("John", "Jeff", "Amy", 0, 0)
crp_100.cdai_rem <- c("John", "Jeff", 0, 0, 0)
eur.cdai_rem     <- c("John", "Jeff", 0, 0, 0)
df3 <- data.frame(bmi_100.crp_100, bmi_100.eur, bmi_100.cdai_rem, crp_100.eur, 
crp_100.cdai_rem)
print(df3)
r networking nodes analysis edges
1个回答
0
投票

这不是一个简短、超级简洁的基本 R 答案,但完成比完美更好
尽管是一个

tidyverse
解决方案,但它的要点是
utils::combn
功能。看看吧。

包装和玩具数据:

library(tidyverse)

# Toy data --------------------
toy_df <- structure(
  list(
    id = c("John", "Cindy", "Laura", "Jeff", "Amy"), 
    bmi_100 = c(1, 1, 1, 1, 0), 
    crp_100 = c(1, 0, 0, 1, 1), 
    eur = c(1, 0, 1, 1, 1), 
    cdai_rem = c(1, 1, 0, 1, 0)), 
  class = "data.frame", 
  row.names = c(NA, -5L))

代码:

# Step 1: Longer, tidy format
new_df <- toy_df %>% 
  pivot_longer(-id) %>% 
  arrange(id, name) %>% 
  filter(value !=0)

# Step 2: Finding all combinations with `utils::combn`
new_df <- reframe(new_df, .by = c(id, value), comb = list(combn(name, 2)))

# Step 3: Wrangling and formatting combinations' names
new_df <- new_df %>% 
  mutate(
    comb = map(
      comb, 
      \(x_comb) map_chr(
        1:ncol(x_comb), 
        \(x_col) str_flatten(x_comb[, x_col], collapse = ".")))) %>% 
  
  unnest(comb)

# Step 4: Wider format
new_df <- new_df %>% 
  pivot_wider(names_from = comb, values_from = value) %>% 
  mutate(across(-id, \(x) if_else(x == 1, id, as.character(x))))

# Step 5: Sorting names and replacing NAs
new_df <- map_dfc(2:ncol(new_df), \(x) arrange(new_df[, x], across(1))) %>% 
  mutate(across(everything(), \(x) replace_na(x, "0")))

输出:

> new_df
# A tibble: 5 × 6
  crp_100.eur bmi_100.cdai_rem bmi_100.crp_100 bmi_100.eur cdai_rem.crp_100
  <chr>       <chr>            <chr>           <chr>       <chr>           
1 Amy         Cindy            Jeff            Jeff        Jeff            
2 Jeff        Jeff             John            John        John            
3 John        John             0               Laura       0               
4 0           0                0               0           0               
5 0           0                0               0           0               
# ℹ 1 more variable: cdai_rem.eur <chr>

创建于 2024-04-23,使用 reprex v2.1.0

就我个人而言,我更愿意使用第三步生成的表。
第四步和第五步只是按照您的要求格式化它。
哦,你不需要五个步骤。如果你愿意的话,只需将所有管道连接在一起即可!

# new_df after step 3:
> new_df
# A tibble: 15 × 3
   id    value comb            
   <chr> <dbl> <chr>           
 1 Amy       1 crp_100.eur     
 2 Cindy     1 bmi_100.cdai_rem
 3 Jeff      1 bmi_100.cdai_rem
 4 Jeff      1 bmi_100.crp_100 
 5 Jeff      1 bmi_100.eur     
 6 Jeff      1 cdai_rem.crp_100
 7 Jeff      1 cdai_rem.eur    
 8 Jeff      1 crp_100.eur     
 9 John      1 bmi_100.cdai_rem
10 John      1 bmi_100.crp_100 
11 John      1 bmi_100.eur     
12 John      1 cdai_rem.crp_100
13 John      1 cdai_rem.eur    
14 John      1 crp_100.eur     
15 Laura     1 bmi_100.eur 

就是这样,希望对你有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.