如何将每一行数据帧与 R 中的数据帧进行比较?
How to compare every row of dataframe to dataframe in R?
我想获取与数据框中每隔一行相等的值的数量:
library(tidyverse)
df <- tibble(
a = c(1, 1, 5, 1),
b = c(2, 3, 2, 8),
c = c(2, 6, 2, 2)
)
期望的输出:
# A tibble: 4 x 4
a b c desired_column
<dbl> <dbl> <dbl> <list>
1 1 2 2 <dbl [4]>
2 1 3 6 <dbl [4]>
3 5 2 2 <dbl [4]>
4 1 8 2 <dbl [4]>
在“desired_column”栏中:
第一行:3、1、2、2:
3:是因为第一行的三个值与其本身相比是相同的
1:是因为有一个值在两行和同一列(第一和第二)中具有相同的值:
2:第一行和第三行同一列有两个值相等:
2:第一行和第四行同一列有两个值相等:
“desired_column”的第二行、第三行和第四行是同一过程的结果:
结果中的第 i
个数字是当前行和第 i
行
之间共有的值的个数
我的方法是将数据连接到自身,table 将每个值与每个原始行中该列的值进行比较。然后我们计算比赛次数并再次扩大范围。
df %>%
rowid_to_column() %>%
pivot_longer(-rowid) -> df2
left_join(df2, df2, by = "name") %>%
count(rowid.x, rowid.y, wt = value.x == value.y) %>% # Edit - shorter
pivot_wider(names_from = rowid.y, values_from = n) %>%
nest(desired_column = c(`1`:`4`)) %>%
select(-rowid.x) -> matches
bind_cols(df, matches)
# A tibble: 4 x 4
a b c desired_column
<dbl> <dbl> <dbl> <list>
1 1 2 2 <tibble [1 × 4]>
2 1 3 6 <tibble [1 × 4]>
3 5 2 2 <tibble [1 × 4]>
4 1 8 2 <tibble [1 × 4]>
> matches %>%
+ unnest(cols = c(desired_column))
# A tibble: 4 x 4
`1` `2` `3` `4`
<int> <int> <int> <int>
1 3 1 2 2
2 1 3 0 1
3 2 0 3 1
4 2 1 1 3
您可以这样做:简而言之,对于数据框的每一行,复制它以创建一个新的数据框,并将所有值更改为该行,并将该数据框与原始数据框进行比较(值是否相同) . rowSums
每个比较都会给你你想要的向量。
# Create the desired output in list
lst <-
lapply(1:nrow(df), function(nr) {
rowSums(replicate(nrow(df), df[nr, ], simplify = FALSE) %>%
do.call("rbind", .) == df)})
# To create the desired dataframe
df %>% tibble(desired_column = I(lst))
在最后一行的tibble
调用中,I()
用于将列表输出作为列。
另一种方法是使用几个 for 循环创建一个函数:
count_combs <- function(df){
output <- list()
vector <- NULL
for(i in 1:nrow(df)){
for(j in 1:nrow(df)){
vector[j] <- sum(df[i,] %in% df[j,])
}
output[[i]] <- vector
}
return(output)
}
df$desired_column<- count_combs(df)
此处 count_combs 函数计算每行由 i 迭代一次并由 j 迭代一次的组合,每次行元素为比较行的 %in% 时求和。
我想获取与数据框中每隔一行相等的值的数量:
library(tidyverse)
df <- tibble(
a = c(1, 1, 5, 1),
b = c(2, 3, 2, 8),
c = c(2, 6, 2, 2)
)
期望的输出:
# A tibble: 4 x 4
a b c desired_column
<dbl> <dbl> <dbl> <list>
1 1 2 2 <dbl [4]>
2 1 3 6 <dbl [4]>
3 5 2 2 <dbl [4]>
4 1 8 2 <dbl [4]>
在“desired_column”栏中: 第一行:3、1、2、2:
3:是因为第一行的三个值与其本身相比是相同的
1:是因为有一个值在两行和同一列(第一和第二)中具有相同的值:
2:第一行和第三行同一列有两个值相等:
2:第一行和第四行同一列有两个值相等:
“desired_column”的第二行、第三行和第四行是同一过程的结果:
结果中的第 i
个数字是当前行和第 i
行
我的方法是将数据连接到自身,table 将每个值与每个原始行中该列的值进行比较。然后我们计算比赛次数并再次扩大范围。
df %>%
rowid_to_column() %>%
pivot_longer(-rowid) -> df2
left_join(df2, df2, by = "name") %>%
count(rowid.x, rowid.y, wt = value.x == value.y) %>% # Edit - shorter
pivot_wider(names_from = rowid.y, values_from = n) %>%
nest(desired_column = c(`1`:`4`)) %>%
select(-rowid.x) -> matches
bind_cols(df, matches)
# A tibble: 4 x 4
a b c desired_column
<dbl> <dbl> <dbl> <list>
1 1 2 2 <tibble [1 × 4]>
2 1 3 6 <tibble [1 × 4]>
3 5 2 2 <tibble [1 × 4]>
4 1 8 2 <tibble [1 × 4]>
> matches %>%
+ unnest(cols = c(desired_column))
# A tibble: 4 x 4
`1` `2` `3` `4`
<int> <int> <int> <int>
1 3 1 2 2
2 1 3 0 1
3 2 0 3 1
4 2 1 1 3
您可以这样做:简而言之,对于数据框的每一行,复制它以创建一个新的数据框,并将所有值更改为该行,并将该数据框与原始数据框进行比较(值是否相同) . rowSums
每个比较都会给你你想要的向量。
# Create the desired output in list
lst <-
lapply(1:nrow(df), function(nr) {
rowSums(replicate(nrow(df), df[nr, ], simplify = FALSE) %>%
do.call("rbind", .) == df)})
# To create the desired dataframe
df %>% tibble(desired_column = I(lst))
在最后一行的tibble
调用中,I()
用于将列表输出作为列。
另一种方法是使用几个 for 循环创建一个函数:
count_combs <- function(df){
output <- list()
vector <- NULL
for(i in 1:nrow(df)){
for(j in 1:nrow(df)){
vector[j] <- sum(df[i,] %in% df[j,])
}
output[[i]] <- vector
}
return(output)
}
df$desired_column<- count_combs(df)
此处 count_combs 函数计算每行由 i 迭代一次并由 j 迭代一次的组合,每次行元素为比较行的 %in% 时求和。