从 R 中具有不同行长的数据帧创建关联矩阵

Posted

技术标签:

【中文标题】从 R 中具有不同行长的数据帧创建关联矩阵【英文标题】:Creating an incidence matrix from data frame with distinct row lengths in R 【发布时间】:2022-01-16 23:44:42 【问题描述】:

我有一个空格分隔的文件,类似于:

# 1_1 AAA ABA AAB BBA
# 1_2 ABA AAA ABB BAA
# 1_3 ABA BAA
# 1_4 AAA BBB ABB

但是,行的内容(我们称它们为“单词”)包含更多字符(大约 20 个)。每行中的单词数量各不相同(从不到 10 个到几十个)。我想使用 R 创建一个关联矩阵,其中每个唯一单词都是一列,行名将保留为行名,如下所示:

#     AAA AAB ABA ABB BAA BBA BBB
# 1_1  1   1   1   0   0   1   0
# 1_2  1   0   1   1   1   0   0
# 1_3  0   0   1   0   1   0   0
# 1_4  1   0   0   1   0   0   1

列顺序不相关。非常感谢任何建议,欢迎基础和软件包解决方案。谢谢!

【问题讨论】:

【参考方案1】:

unite/cSplit_e 的选项

library(dplyr)
library(tidyr)
library(splitstackshape)
library(stringr)
df %>% 
  unite(new, starts_with('col'), na.rm = TRUE) %>% 
  cSplit_e(., "new", sep="_", type = "character", fill = 0, drop = TRUE) %>% 
  rename_with(~ str_remove(., "new_"), -id)
   id AAA AAB ABA ABB BAA BBA BBB
1 1_1   1   1   1   0   0   1   0
2 1_2   1   0   1   1   1   0   0
3 1_3   0   0   1   0   1   0   0
4 1_4   1   0   0   1   0   0   1

【讨论】:

【参考方案2】:

试试下面的代码

> +(t(table(stack(as.data.frame(t(`row.names<-`(df[-1], df$id)))))) > 0)
     values
ind   AAA AAB ABA ABB BAA BBA BBB
  1_1   1   1   1   0   0   1   0
  1_2   1   0   1   1   1   0   0
  1_3   0   0   1   0   1   0   0
  1_4   1   0   0   1   0   0   1

【讨论】:

【参考方案3】:

tidyverse

library(tidyverse)

df <-
  structure(
    list(
      id = c("1_1", "1_2", "1_3", "1_4"),
      col_1 = c("AAA", "ABA", "ABA", "AAA"),
      col_2 = c("ABA", "AAA", "BAA", "BBB"),
      col_3 = c("AAB", "ABB", NA, "ABB"),
      col_4 = c("BBA", "BAA", NA, NA)
    ),
    class = "data.frame",
    row.names = c(NA,-4L)
  )

df %>%
  pivot_longer(-id, values_drop_na = TRUE) %>%
  pivot_wider(
    id_cols = id,
    names_from = value,
    values_from = value,
    values_fn = length,
    values_fill = 0
  )
#> # A tibble: 4 x 8
#>   id      AAA   ABA   AAB   BBA   ABB   BAA   BBB
#>   <chr> <int> <int> <int> <int> <int> <int> <int>
#> 1 1_1       1     1     1     1     0     0     0
#> 2 1_2       1     1     0     0     1     1     0
#> 3 1_3       0     1     0     0     0     1     0
#> 4 1_4       1     0     0     0     1     0     1

由reprex package (v2.0.1) 于 2021 年 12 月 13 日创建

data.table

library(data.table)
library(magrittr)

setDT(df)

melt(df, id.vars = "id") %>% 
  na.omit() %>% 
  dcast(formula = id ~ value, fun.aggregate = length)
#>     id AAA AAB ABA ABB BAA BBA BBB
#> 1: 1_1   1   1   1   0   0   1   0
#> 2: 1_2   1   0   1   1   1   0   0
#> 3: 1_3   0   0   1   0   1   0   0
#> 4: 1_4   1   0   0   1   0   0   1

由reprex package (v2.0.1) 于 2021 年 12 月 13 日创建

基础

df_stack <- stack(df, select = -id)
df_stack$id <- rep(df$id, ncol(df) - 1)
+(with(df_stack, table(id, values)))
#>      values
#> id    AAA AAB ABA ABB BAA BBA BBB
#>   1_1   1   1   1   0   0   1   0
#>   1_2   1   0   1   1   1   0   0
#>   1_3   0   0   1   0   1   0   0
#>   1_4   1   0   0   1   0   0   1

由reprex package (v2.0.1) 于 2021 年 12 月 13 日创建

【讨论】:

谢谢!我使用以下代码导入数据:n = max(count.fields("file_name.txt")) data = read.table("file_name.txt", h = F, col.names = c("id", paste("V", seq_len(n))), fill = T) 我更喜欢使用 tidyverse 解决方案,但是出现以下错误:错误:必须命名第 35 列。使用 .name_repair 指定修复。我无法弄清楚如何解决它。 data.table 解决方案有效,所以我坚持这样做。

以上是关于从 R 中具有不同行长的数据帧创建关联矩阵的主要内容,如果未能解决你的问题,请参考以下文章

Rcpp - 从矩阵/数据帧列表中提取行

使用 Pandas 将 CSV 读入具有不同行长的数据帧

如何将两列“计数”矩阵转换为 R 中的二进制向量? [复制]

如何使用 R 将数据帧/矩阵写入 CSV,但值中有逗号

如何将 4 行数据帧转换为 R 中的 2*2 矩阵?

来自具有太多列的数据帧的 Python 散点矩阵