我有两组数据帧。一种是字符串的组合,其中有两列,具有不同类型的食物:
#df.combination
[,1] [,2]
[1,] "Apple" "Orange"
[2,] "Apple" "Pear"
[3,] "Apple" "Avocado"
[4,] "Orange" "Pear"
[5,] "Orange" "Avocado"
[6,] "Pear" "Avocado"
另一个是主要的"主要"数据框包含三列食物(" id"" date"" food1"" food2"" food3")包含其中一些组合:
#df.main
[,1] [,2] [,3] [,4] [,5]
[1,] "1234" "3/29" "Sala" "Pear" "Avocado"
[2,] "1235" "3/30" "Apple" "Pear" "Meat"
[3,] "1236" "4/1" "Orange" "Juice" "Apple"
[4,] "1237" "4/2" "Pear" "Avocado""Turkey"
如果我想编写一个搜索 df.main 的脚本,并选择包含 df.combination [1,] 中所有元素的行,那么" Apple"和#34; Orange"),我怎么能这样做?食物不必是任何顺序。这排只需要包含食物。 (即 df.main [3,] )。
以下是我希望看到的示例输出。如果我搜索" Orange"和#34; Apple" ( df.main 中的 df.combination [1,] ),我希望看到行 df.main [2,]的ID
#search df.main for row containing df.combination[1,]
#output:
#1236
谢谢!任何帮助真的很感激。
答案 0 :(得分:1)
你可以尝试
f1 <- function(dat1, dat2, rowindex){
Indx <- apply(dat1[,grep('food', colnames(dat1))], 1,
function(x) all(unlist(dat2[rowindex,]) %in% x))
dat1[Indx,1]
}
f1(df.main, df.combination,1)
#[1] 1236
f1(df.main, df.combination,2)
#[1] 1235
f1(df.main, df.combination,3)
#integer(0)
df.main <- structure(list(id = 1234:1237, date = c("3/29", "3/30",
"4/1",
"4/2"), food1 = c("Sala", "Apple", "Orange", "Pear"),
food2 = c("Pear",
"Pear", "Juice", "Avocado"), food3 = c("Avocado", "Meat", "Apple",
"Turkey")), .Names = c("id", "date", "food1", "food2",
"food3"), class = "data.frame", row.names = c(NA, -4L))
df.combination <- structure(list(V1 = c("Apple", "Apple", "Apple",
"Orange", "Orange",
"Pear"), V2 = c("Orange", "Pear", "Avocado", "Pear", "Avocado",
"Avocado")), .Names = c("V1", "V2"), class = "data.frame",
row.names = c(NA, -6L))
答案 1 :(得分:0)
为此,您可以编写一个扩展匹配函数的函数来过滤包含特定向量的所有值的记录,如下所示:
match_filter <- function(df, match_to) {
apply(df,
1,
function(row) {
!any(is.na(match(match_to, row)))
})
}
因此,函数match_filter
有两个参数:第一个是df
,在这种情况下,它将是你的df.main
数据集(或者它的一个子集 - 正如我们将要看到的) 。第二个是match_to
,它是我们想要匹配的向量,或者我们希望在df
中的每个记录中包含其所有值。
该功能易于理解,但是,查看其中的一些组件非常有用。在这种情况下match
函数正在做的是match_to
向量中的每个值,返回row
向量中的索引(df
中的一行)。如果在row
中未找到该值,则返回NA
。这是在您提供的数据集的第二行上运行匹配的示例:
> match(df.combination[1,], df.main[2,])
[1] 3 NA
现在,为了使记录row
满足我们在这种情况下的需求,match
函数返回的向量不应该有NA
个值。这就是我们将match(match_to, row)
函数与!any(is.na())
包装起来的原因。因此,如果NA
的返回值中有match
个,那么我们要丢弃该记录。
我们在apply
函数中包含所有这些内容的原因是因为我们希望在function(row){...}
的每一行上运行内部函数(df
)并且这样做apply
函数用于什么。
这是在数据集上使用上面定义的函数的示例:
> df.main[ match_filter(df.main[,3:5], df.combination[1,]),]
id date food1 food2 food3
3 1236 4/1 Orange Juice Apple
> subset(df.main, match_filter(df.main[,3:5], df.combination[1,]))
id date food1 food2 food3
3 1236 4/1 Orange Juice Apple
正如您所看到的,因为在这种情况下,您对3:5
数据框中的df.main
列感兴趣,我们只需将它们传递给match_filter
函数。
<强>更新强>
如果您想使用可以采用任意数量组合的功能,那么我们需要更新match_filter
以适应这种情况。更新非常简单,遵循我们之前看到的相同逻辑:
match_filter <- function(df, match_to) {
apply(df,
1,
function(row1) {
any(apply(match_to,
1,
function(row2) {
!any(is.na(match(row2, row1)))
}))
})
}
现在match_filter
函数是一个更通用的函数,可以采用任意数量的组合并检查row1
是否具有任何这些组合。在这种情况下,match_to
可以是与df.combination
对应的数据框。以下是使用新功能的几个示例:
首先,我添加了这个假设记录用于说明目的:
df.main[5,] <- c("1238", "4/3", "Apple", "Avocado", "Orange" )
以下是如何使用该功能的示例:
# Example showing how the function
# works with only the first row of df.combination
> df.main[ match_filter(df.main[,3:5], df.combination[1,]),]
id date food1 food2 food3
3 1236 4/1 Orange Juice Apple
5 1238 4/3 Apple Avocado Orange
# The first 2 rows of df.combination
> df.main[ match_filter(df.main[,3:5], df.combination[1:2,]),]
id date food1 food2 food3
2 1235 3/30 Apple Pear Meat
3 1236 4/1 Orange Juice Apple
5 1238 4/3 Apple Avocado Orange
# All the rows in the df.combination dataframe
> df.main[ match_filter(df.main[,3:5], df.combination),]
id date food1 food2 food3
1 1234 3/29 Sala Pear Avocado
2 1235 3/30 Apple Pear Meat
3 1236 4/1 Orange Juice Apple
4 1237 4/2 Pear Avocado Turkey
5 1238 4/3 Apple Avocado Orange