繁体   English   中英

从多列中选择-R

[英]Select from Multiple Columns - R

我有两组数据框。 一种是字符串的组合,其中有两列,食物的类型不同:

#df.combination

      [,1]     [,2] 
[1,] "Apple" "Orange"         
[2,] "Apple" "Pear"         
[3,] "Apple" "Avocado" 
[4,] "Orange" "Pear"   
[5,] "Orange" "Avocado"
[6,] "Pear" "Avocado"

另一个是大型的“主要”数据框,其中包含三列食物(“ id”,“日期”,“ 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”和“ Orange”),我该怎么做? 食物不必乱序。 该行只需要容纳食物。 (即df.main [3,] )。

这是我想看到的示例输出。 如果我在df.main中搜索“ Orange”和“ Apple”(所以df.combination [1,] ),我想查看df.main [2,]行的ID。

#search df.main for row containing df.combination[1,]
#output:
#1236

谢谢! 任何帮助真的很感激。

你可以试试

 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))

为此,您可以编写一个扩展match函数的函数,以对包含某个向量的所有值的记录进行过滤,如下所示:

match_filter <- function(df, match_to) { 
    apply(df, 
          1, 
          function(row) {
              !any(is.na(match(match_to, row)))
          })
}

因此,功能match_filter有2个参数:第一个是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值。 这就是为什么我们用!any(is.na())包装match(match_to, row)函数的原因。 因此,如果match的返回值中有任何NA ,那么我们要丢弃该记录。

我们将所有这些包装在apply函数中的原因是因为我们要在df每一行上运行内部函数( function(row){...} ),这就是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

如您所见,由于在这种情况下您对df.main数据帧中的3:5列感兴趣,因此我们只将它们传递给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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM