检查一对列是否在数据框的一行中
Check if pair of columns is in a row of a data frame
我想知道是否有任何有效的方法来检查给定的一对(或多于两列的元组)是否在数据框中。
例如,假设我有以下数据框:
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
我想检查这个 table 是否包含成对列的列表,比如说:
(a,b), (a,c), (a,e), (c,a), (c,g), (a,f)
它应该输出到:
FALSE FALSE TRUE FALSE TRUE FALSE
编辑:添加了一对新的 (a,f) 以避免混淆
我想通过将列连接成字符串然后与 %in% 进行比较来实现这一点,但这效率很低。我也想过用 dplyr 的过滤器做一个循环,但是当 table 很大并且需要转换格式(即写几行)时也需要很长时间。
在 R 中有什么有效的方法可以做到这一点吗?
这似乎是 apply
或 lapply
函数族之一的情况。如果将 pairs.list
定义为 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 中性能基准测试的专家,所以我不确定。
如果只需要检查列组合是否在table中,
您可以使用 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)
我想知道是否有任何有效的方法来检查给定的一对(或多于两列的元组)是否在数据框中。
例如,假设我有以下数据框:
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
我想检查这个 table 是否包含成对列的列表,比如说: (a,b), (a,c), (a,e), (c,a), (c,g), (a,f)
它应该输出到:
FALSE FALSE TRUE FALSE TRUE FALSE
编辑:添加了一对新的 (a,f) 以避免混淆
我想通过将列连接成字符串然后与 %in% 进行比较来实现这一点,但这效率很低。我也想过用 dplyr 的过滤器做一个循环,但是当 table 很大并且需要转换格式(即写几行)时也需要很长时间。
在 R 中有什么有效的方法可以做到这一点吗?
这似乎是 apply
或 lapply
函数族之一的情况。如果将 pairs.list
定义为 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 中性能基准测试的专家,所以我不确定。
如果只需要检查列组合是否在table中,
您可以使用 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)