我有一张满是名字的数据。
对于dataframe中的给定行,我希望将该行与df中的每一行进行比较,并确定匹配名称的数量是否小于或等于每一行4。
玩具示例,其中第3行是感兴趣的行
。
因此,首先我们比较第3行和第1行,并看到名称重叠为3,这符合<= 4的条件。
然后,我们将第3行与第2行进行比较,发现名称重叠为5,这不符合<=4的条件,最终返回了一个失败的条件,即上面的每一行都是<=4。
现在,我正在使用for循环执行此操作,但是对于我所使用的数据帧大小来说,速度太慢了。
发布于 2019-11-15 15:57:59
示例数据
df <- as.data.frame(rbind(
c("Jim","Dwight","Michael","Andy","Stanley","Creed"),
c("Jim","Dwight","Angela","Pam","Ryan","Jan"),
c("Jim","Dwight","Angela","Pam","Creed","Ryan")
), stringsAsFactors = FALSE)
df
# V1 V2 V3 V4 V5 V6
# 1 Jim Dwight Michael Andy Stanley Creed
# 2 Jim Dwight Angela Pam Ryan Jan
# 3 Jim Dwight Angela Pam Creed Ryan操作和输出(在列上应用%in%并接受rowSums)
out_lgl <- rowSums(sapply(df, '%in%', unlist(df[3,]))) <= 4
out_lgl
# [1] TRUE FALSE FALSE
which(out_lgl)
# [1] 1解释:
对于每一列,将每个元素与第三行(向量unlist(df[3,]))进行比较。输出是一个逻辑值矩阵,如果有匹配,则其维度与df、TRUE相同。
sapply(df, '%in%', unlist(df[3,]))
# V1 V2 V3 V4 V5 V6
# [1,] TRUE TRUE FALSE FALSE FALSE TRUE
# [2,] TRUE TRUE TRUE TRUE TRUE FALSE
# [3,] TRUE TRUE TRUE TRUE TRUE TRUE然后,我们可以对TRUEs进行求和,以查看每一行的匹配数。
rowSums(sapply(df, '%in%', unlist(df[3,])))
# [1] 3 5 6编辑:
我在上面创建的stringsAsFactors = FALSE中添加了df选项。然而,据我所知,%in%的输出是相同的,无论是比较不同级别的因素还是不同的字符,所以我不认为这会以任何方式改变结果。见下面的例子
x <- c('b', 'c', 'z')
y <- c('a', 'b', 'g')
all.equal(x %in% y, factor(x) %in% factor(y))
# [1] TRUE发布于 2019-11-15 21:24:46
类似于IceCreamToucan的解决方案,但适用于任何行。
对于data.frame:
df <- as.data.frame(rbind(
c("Jim","Dwight","Michael","Andy","Stanley","Creed"),
c("Jim","Dwight","Angela","Pam","Ryan","Jan"),
c("Jim","Dwight","Angela","Pam","Creed","Ryan")
)对于任何第一行:
f <- function(i) {
if(i == 1) return(T)
r <- vapply(df[1:(i-1),], '%in%', unlist(df[i,]), FUN.VALUE = logical(i-1))
out_lgl <- rowSums(as.matrix(r)) <= 4
return(all(out_lgl))
}https://stackoverflow.com/questions/58880523
复制相似问题