r - 使用第二个数据帧值按值过滤数据帧
问题描述
我总是遇到循环问题,所以我在这里问。2个数据框。1 个非常大,1 个小得多。下面的示例版本。
Dataframe 1
ID Value
1 apples
1 apples
1 bananas
1 grapes
1 mangoes
1 oranges
1 grapes
1 apples
1 grapes
2 apples
2 apples
2 passionfruits
2 bananas
2 apples
2 apples
2 passionfruits
2 grapes
2 mangoes
2 apples
3 apples
3 bananas
3 oranges
3 apples
3 grapes
3 grapes
3 passionfruits
3 passionfruits
3 oranges
4 apples
4 oranges
4 mangoes
4 bananas
4 grapes
4 grapes
4 grapes
4 apples
4 oranges
4 grapes
4 mangoes
4 mangoes
4 apples
4 oranges
5 passionfruits
5 apples
5 oranges
5 oranges
5 mangoes
5 grapes
5 apples
5 bananas
Dataframe 2
Value
apples
apples
bananas
grapes
mangoes
mangoes
grapes
apples
apples
数据帧 1 中的不同 ID 被视为集合。数据框 2 的整体将与其中一组近似或精确匹配。我知道有很多代码可以使用整个数据帧 2 与 1 匹配进行过滤。但这不是我需要的。我要求它在附加条件的情况下按值顺序过滤。条件应该是之前的值是否匹配。
因此,在此示例中,第一个值没有任何反应,因为所有 ID 都有“苹果”。第二个值 = 'apples' 给定先前的值 ='apples' 过滤掉 ID = 4,因为它不包含连续出现两次的 'apples'。现在在过滤后的数据帧 1 中,我们搜索第三个值,依此类推。它仅在数据帧 1 中保留 1 个 ID 集时停止。因此在这种情况下,在第 3 次迭代之后。结果应该是
Dataframe 1
ID Value
1 apples
1 apples
1 bananas
1 grapes
1 mangoes
1 oranges
1 grapes
1 apples
1 grapes
解决方案
一种可能的方法data.table
(改编自我的回答here):
# load packages
library(data.table)
# create a function which calculates match-score with 'df2$Value'
maxscore <- function(x, y) {
m <- mapply('==', shift(x, type = 'lead', n = 0:(length(y) - 1)), y)
max(rowSums(m, na.rm = TRUE))
}
# calculate the match-score for each group
# and filter out the other groups
setDT(df1)[, score := maxscore(Value, df2$Value), by = ID
][score == max(score)][, score := NULL][]
这使:
ID Value 1: 1 apples 2: 1 apples 3: 1 bananas 4: 1 grapes 5: 1 mangoes 6: 1 oranges 7: 1 grapes 8: 1 apples 9: 1 grapes
您也可以在 -chain 中使用该功能dplyr
(但您仍然需要data.table
-package 用于shift
-function):
library(dplyr)
df1 %>%
group_by(ID) %>%
mutate(m = maxscore(Value, df2$Value)) %>%
ungroup() %>%
filter(m == max(m)) %>%
select(-m)
-function 的另一种实现maxscore
(灵感来自@doscendo's answer here):
maxscore2 <- function(x, y) {
w <- which(x == y[1])
v <- sapply(w, function(i) sum(x[i:(i+(length(y)-1))] == y, na.rm = TRUE))
max(v)
}
推荐阅读
- java - 如果我的应用目标 sdk 版本为 30,它如何在具有较低 sdk 的手机中工作
- android - Android Studio 耳机控制按钮点击事件错误
- docker - HyperLedger Fabric 和 Docker Swarm:握手失败并出现致命错误 SSL_ERROR_SSL
- javascript - 重新启动网页时,暗模式首选项丢失
- selenium - 自动日期采摘硒
- python - 我想在我的文本文件中打印以特定许可证号开头的行,但这仅在许可证号在第一行时才会打印出来
- arrays - Excel:VLookup 公式对数组值的多个(排序)结果
- c++ - 当 j=3 时,为什么它在 a 和 b 之后打印 a 和 b 而不是 c 在第二个循环中打印 ab 对于 which (counter &(1<
我一直在试图理解为什么输出不是所有元素都只打印第一个和第二个单独打印而不是第三个它开始组合而不是单个三分之一,因为当 j=3 时仍然在第二个循环中(计数器&(1<<j)) 也是如此。所以这里是代码:
- java - 在Java中将连续两个json的字符串拆分为两个json
- typo3 - Extbase 正确的关系发现