tidyverse:将 data.frame 的每一行与另一个 data.frame 的一行进行比较
tidyverse: Comparing each row of a data.frame with a single row from another data.frame
我想以整洁的方式比较 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
在基地
apply(df1,1, function(x) sum(x == df2))
[1] 1 2
使用 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))
带有 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
要么先拆分它,然后检查身份:
library(purrr)
asplit(df1,1) %>% map_dbl(~sum(.==df2))
或者只映射行号:
1:nrow(df1) %>% map_dbl(function(i)sum(df1[i,]==df2))
[1] 1 2
基础 R 解决方案。
按行比较求和:
rowSums(mapply(`==`, df1, df2))
#[1] 1 2
编辑。
以上是这个 post 的新版本。原始按列求和。这是代码。
return值是一个逻辑向量列表,然后*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
我想以整洁的方式比较 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
在基地
apply(df1,1, function(x) sum(x == df2))
[1] 1 2
使用 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))
带有 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
要么先拆分它,然后检查身份:
library(purrr)
asplit(df1,1) %>% map_dbl(~sum(.==df2))
或者只映射行号:
1:nrow(df1) %>% map_dbl(function(i)sum(df1[i,]==df2))
[1] 1 2
基础 R 解决方案。
按行比较求和:
rowSums(mapply(`==`, df1, df2))
#[1] 1 2
编辑。
以上是这个 post 的新版本。原始按列求和。这是代码。
return值是一个逻辑向量列表,然后*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