检查每一行的数据框的条件,即逐行

Check a condition of a data frame for each row, that is row by row

我有一个包含列 a1,b1,a2,b2,a3,b3 的数据框 df。另一方面,我有一个向量 vec.

我想为 df 的每一行获取列 b1,b2,b3 中的元素在 vec.

中的时间

我的意思是,如果在一行中,b1b2列的元素在vec,但b3列的元素不在在 vec 我想得到 2。如果 b1,b2,b3 列中一行元素的 none 在 vec 中(如果它们缺少值),我想得到 0.

如果我输入 rowSums(!df[,c(b1,b2,b3)] %in% vec),我会得到错误 'x' must be an array of at least two dimensions,因为里面的条件是一行,而不是 df 的行数。我做的其他尝试也失败了。

其中之一:只有 1 行的示例:

df[1,c('b1','b2','b3')]: 6 -1 NA

如果我把

df[1,c('b1','b2','b3')]==c(-1,-2),

我明白了

FALSE FALSE NA

我想去哪里

FALSE TRUE NA

提前致谢!

%in% 作用于 vector,因此我们循环遍历感兴趣的列并获得 Reduce

的元素总和
Reduce("+", lapply(df[c('b1', 'b2', 'b3')], function(x) !x %in% vec))

如果我们按行进行比较,那么我们可以使用apply

rowSums(t(apply(df[c('b1', 'b2', 'b3')], 1, function(x) !x %in% vec)))

或将其转换为 matrix,然后与 %in% 进行比较,更改尺寸并执行 rowSums

m1 <- as.matrix(df[c('b1', 'b2', 'b3')])
rowSums(`dim<-`(!m1 %in% vec, dim(m1)))

目前,解决方案可能是:

df %>% mutate(new = rowSums(across(matches("^b\d$"), ~`%in%`(.,vec))))

以范例

library(tidyverse)
vec <- c(7, 8)
df <- anscombe %>% 
          mutate(across(starts_with("y"),floor))
df
   x1 x2 x3 x4 y1 y2 y3 y4
1  10 10 10  8  8  9  7  6
2   8  8  8  8  6  8  6  5
3  13 13 13  8  7  8 12  7
4   9  9  9  8  8  8  7  8
5  11 11 11  8  8  9  7  8
6  14 14 14  8  9  8  8  7
7   6  6  6  8  7  6  6  5
8   4  4  4 19  4  3  5 12
9  12 12 12  8 10  9  8  5
10  7  7  7  8  4  7  6  7
11  5  5  5  8  5  4  5  6

一个人可以做到:

df %>% 
    mutate(new = rowSums(across(starts_with("y"), ~`%in%`(.,vec))))
   x1 x2 x3 x4 y1 y2 y3 y4 new
1  10 10 10  8  8  9  7  6   2
2   8  8  8  8  6  8  6  5   1
3  13 13 13  8  7  8 12  7   3
4   9  9  9  8  8  8  7  8   4
5  11 11 11  8  8  9  7  8   3
6  14 14 14  8  9  8  8  7   3
7   6  6  6  8  7  6  6  5   1
8   4  4  4 19  4  3  5 12   0
9  12 12 12  8 10  9  8  5   1
10  7  7  7  8  4  7  6  7   2
11  5  5  5  8  5  4  5  6   0