4

我想知道是否有任何有效的方法来检查给定的列对(或两个以上的元组)是否在数据框中。

例如,假设我有以下数据框:

df=data.frame(c("a","b","c","d"),c("e","f","g","h"),c(1,0,0,1))
names(df)=c('col1','col2','col3')

  col1 col2 col3
1    a    e    1
2    b    f    0
3    c    g    0
4    d    h    1

我想检查这个表是否包含列对的列表,比如:(a,b), (a,c), (a,e), (c,a), (c,g), (a ,F)

它应该向其输出:

FALSE FALSE TRUE FALSE TRUE FALSE

编辑:添加了一对新的 (a,f) 以避免混淆

我想通过将列连接成字符串然后与 %in% 进行比较来做到这一点,但这非常低效。我也想过用dplyr的过滤器做一个循环,但是当表格很大并且需要转换格式(即写几行)时,它也需要相当长的时间。

在 R 中是否有任何有效的方法来实现这一点?

4

2 回答 2

2

这似乎是函数applylapply函数家族之一的情况。如果定义pairs.list为 a list,则可以使用lapply

df = data.frame(c("a","b","c","d"), c("e","f","g","h"), c(1,0,0,1))
names(df) = c('col1','col2','col3')
pairs.list = list(c("a", "b"), c("a", "c"), c("a", "e"), c("c", "a"), c("c", "g"))
lapply(pairs.list, FUN=function(x){any(df$col1==x[[1]] & df$col2==x[[2]])})

[[1]]
[1] FALSE

[[2]]
[1] FALSE

[[3]]
[1] TRUE

[[4]]
[1] FALSE

[[5]]
[1] TRUE

new.pairs = list(c("a", "b"), c("a", "c"), c("e", "a"), c("c", "a"), c("c", "g"))

lapply(new.pairs, FUN=function(x){any(df$col1==x[[1]] & df$col2==x[[2]])})

[[1]]
[1] FALSE

[[2]]
[1] FALSE

[[3]]
[1] FALSE

[[4]]
[1] FALSE

[[5]]
[1] TRUE

使用这种方法,如果您想知道df匹配的行,您可以摆脱any()调用并接收一个布尔向量列表,其中每个向量的长度与 相同df

我认为这应该是相对有效的,因为它都是布尔逻辑而不是字符串操作,但我不是 R 性能基准测试专家,所以我不确定。

于 2015-07-24T15:07:22.487 回答
1

如果您只需要检查列组合是否在表中,则可以使用unique减少比较次数:

df=data.frame(c("a","b","c","d"),c("e","f","g","h"),c(1,0,0,1), stringsAsFactors=FALSE)
names(df)=c('col1','col2','col3')

df$to_check = paste(df$col1, df$col2, sep=',')
cols <- c("a,b", "a,c", "a,e", "c,a", "c,g")

cols %in% unique(df$to_check)
于 2015-07-24T15:09:16.247 回答