【问题标题】:tidyverse: Comparing each row of a data.frame with a single row from another data.frametidyverse:将 data.frame 的每一行与另一个 data.frame 的单行进行比较
【发布时间】:2020-06-18 18:19:20
【问题描述】:

我想以整齐的方式比较df1 的每一行与df2 的单行。 请有任何提示。

df1 <-
  structure(
    list(
        Q1 = c("a", "a")
      , Q2 = c("b", "a")
      , Q3 = c("a", "a")
      , Q4 = c("b", "a")
      )
    , class = "data.frame"
    , row.names = c(NA, -2L)
    )

df2 <-
  structure(
    list(
        Q1 = "a"
      , Q2 = "a"
      , Q3 = "b"
      , Q4 = "c"
      )
    , class = "data.frame"
    , row.names = c(NA, -1L)
    )

library(tidyverse)


sum(df1[1, ] == df2)
[1] 1
sum(df1[2, ] == df2)
[1] 2

【问题讨论】:

  • 你能bind_cols这两个dfs吗?

标签: r tidyverse tidytable


【解决方案1】:

在基地

apply(df1,1, function(x) sum(x == df2))

[1] 1 2

【讨论】:

  • 感谢@Daniel 的回答。我的预期输出是 1 和 2。请参阅编辑。
  • @MYaseen208,已修复。
【解决方案2】:

要么先拆分,然后检查身份:

library(purrr)
asplit(df1,1) %>% map_dbl(~sum(.==df2))

或者只是映射行号:

1:nrow(df1) %>% map_dbl(function(i)sum(df1[i,]==df2))
[1] 1 2

【讨论】:

  • 感谢您的精彩回答。如果您指导如何将列输出变异为 df1,将不胜感激
  • 您的意思是将 1,2 作为 df1 中的一列? ``` df1 %>% mutate(y=1:nrow(.) %>% map_dbl(function(i)sum(df1[i,]==df2)))``` 这会起作用。你的data.frame有多大?调用行号更安全...
【解决方案3】:

base R 的选项是rowSums

rowSums(df1 == unlist(df2)[col(df1)])
#[1] 1 2

tidyverse中,我们也可以使用c_across

library(dplyr)
df1 %>% 
    rowwise %>%
    mutate(new = sum(c_across(everything()) == df2)) 
# A tibble: 2 x 5
# Rowwise: 
#  Q1    Q2    Q3    Q4      new
#  <chr> <chr> <chr> <chr> <int>
#1 a     b     a     b         1
#2 a     a     a     a         2

【讨论】:

    【解决方案4】:

    基础 R 解决方案。

    按行比较和求和:

    rowSums(mapply(`==`, df1, df2))
    #[1] 1 2
    

    编辑。

    以上是这篇文章的新版本。原始按列求和。这是代码。

    返回值是一个逻辑向量列表,然后是*apply函数sum

    Map(`==`, df1, df2)
    #$Q1
    #[1] TRUE TRUE
    #
    #$Q2
    #[1] FALSE  TRUE
    #
    #$Q3
    #[1] FALSE FALSE
    #
    #$Q4
    #[1] FALSE FALSE
    
    res <- Map(`==`, df1, df2)
    sapply(res, sum)
    #Q1 Q2 Q3 Q4 
    # 2  1  0  0
    

    单线是

    sapply(Map(`==`, df1, df2), sum)
    

    另一个,更快。

    colSums(mapply(`==`, df1, df2))
    #Q1 Q2 Q3 Q4 
    # 2  1  0  0
    

    【讨论】:

      【解决方案5】:

      使用 purrr 包:

      unlist_df2 <- unlist(df2)
          seq_len(nrow(df1)) %>%
            map_lgl(~identical(unlist(df1[.x,]), unlist_df2))
      

      用于编辑:将 map_lgl 更改为 map_dbl 并与 sum & ==

      unlist_df2 <- unlist(df2)
      seq_len(nrow(df1)) %>%
        map_dbl(~sum(unlist(df1[.x,]) == unlist_df2))
      

      【讨论】:

      • 感谢@det 的回答。我的预期输出是 1 和 2。请参阅编辑。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多