【问题标题】:A tidyverse solution to populating a matrix/data frame填充矩阵/数据框的 tidyverse 解决方案
【发布时间】:2018-02-28 18:57:49
【问题描述】:

我有一个包含单列的数据框(命中)。这填充了独特的搜索结果。

第二个数据框(数据)包含各种搜索查询的结果。列名标识所使用的搜索词,行中填充了搜索结果。

我想构建一个矩阵或另一个数据框,根据搜索结果是否按列填充。

我可以使用带有以下代码的 base R 来做到这一点:

    library(tidyverse)
    hit <- read_csv("hit
                     A1 
                     A3
                     B2
                     B4
                     D3")

    data <- read_csv("Search1, Search2, Search3, Search4
             A1, B4, A3, A1
             B4, D3, NA, B2
             D3, NA, NA, B4")



    search <- c("Search1", "Search2", "Search3", "Search4")

    the_matrix <- matrix(data = NA, nrow = 5, ncol = 4)
    rownames(the_matrix) <- hit$hit 
    colnames(the_matrix) <- search

    for (i in search)
        for (j in 1:3){
            result <- data[[i]][[j]]
            row_index <- which(rownames(the_matrix) == result)
            the_matrix[row_index, i] <- 1
        }

    the_matrix[is.na(the_matrix)] <- 0

在我看来,应该有一种方法可以使用 tidyverse 实现相同的结果,使用第一个数据帧作为起点。从那里开始,使用搜索结果作为填充键逐列引入第二个数据框。

谁能帮忙?

【问题讨论】:

  • read_csv 是一个整洁的 verse 函数。
  • 代码在我的机器上运行。我只是忘了包括图书馆(tidyverse)

标签: r join tidyverse dplyr


【解决方案1】:
data %>% gather(na.rm=T) %>% mutate(p=1L) %>% spread("key", "p", fill=0L)

# A tibble: 5 x 5
  value Search1 Search2 Search3 Search4
  <chr>   <int>   <int>   <int>   <int>
1 A1          1       0       0       1
2 A3          0       0       1       0
3 B2          0       0       0       1
4 B4          1       1       0       1
5 D3          1       1       0       0

【讨论】:

  • 完美。这正是我所追求的。
【解决方案2】:

为了您的信息,您还可以有一个相当优雅的 base r 解决方案

the_matrix=sapply(data,function(x) as.numeric(hit$hit%in%x))
rownames(the_matrix)<-hit$hit

【讨论】:

  • 谢谢你,但我发现 tidyverse 代码的可读性对于像我这样刚开始很少正式指导的人来说是一个真正的优势。当我回顾我的一些旧剧本与我现在写的相比时,它就像粉笔和奶酪。
【解决方案3】:

您可以将map_dfmatch 结合使用,然后将a_tibble 中所有非0s 替换为1L

library(purrr)
library(tidyr)
a_tibble <- map_df(data, ~match(hit[["hit"]], ., nomatch = 0L))
a_tibble[a_tibble != 0] <- 1L
a_tibble %>%
  add_column(., hit = hit$hit, .before = 1)
#  A tibble: 5 x 4
#  hit   Search1 Search2 Search3 Search4
#  <chr>   <int>   <int>   <int>   <int>
#1 A1          1       0       0       1
#2 A3          0       0       1       0
#3 B2          0       0       0       1
#4 B4          1       1       0       1
#5 D3          1       1       0       0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-01
    • 1970-01-01
    • 2018-09-03
    • 1970-01-01
    • 2021-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多