如何比较R中不同data.Frame中的两列

如何比较R中不同data.Frame中的两列,r,for-loop,matrix,dataframe,compare,R,For Loop,Matrix,Dataframe,Compare,我在R公司做第一个真正的项目,遇到了一个问题。我试图比较两个不同data.Frame中的两列。我试着运行代码 matrix1 = matrix for (i in 1:2000){ if(data.QW[i,1] == data.RS[i,1]){ matrix1[i,1]== "True" } else{ matrix1[i,1]== "False" } } 我得到了这个错误: Error in Ops.factor(data.QW[i,1], data.RS

我在R公司做第一个真正的项目,遇到了一个问题。我试图比较两个不同data.Frame中的两列。我试着运行代码

matrix1 = matrix
for (i in 1:2000){
  if(data.QW[i,1] == data.RS[i,1]){
    matrix1[i,1]== "True"
  }
  else{
    matrix1[i,1]== "False"
  }
}
我得到了这个错误:

Error in Ops.factor(data.QW[i,1], data.RS[i,1]) : 
  level sets of factors are different
我认为这可能是因为QW和RS的行长度不同。但我正在尝试查看这些错误在不同的data.frames中的位置,并根据源文档修复它们

我也不确定矩阵是否能解决这个问题,或者我是否需要将它变成一个向量,并每次将它rbind到矩阵中


对此,如有任何好的阅读,我们将不胜感激。

如评论中所述,提供一个包含数据框内容的可复制示例将非常有帮助


根据问题主题的听起来,您似乎希望将数据帧A的第1列与数据帧B的第1列进行比较,并将结果存储在逻辑向量中。如果该摘要准确无误,请查看。

如评论中所述,提供一个包含数据框内容的可复制示例将很有帮助


根据问题主题的听起来,您似乎希望将数据帧A的第1列与数据帧B的第1列进行比较,并将结果存储在逻辑向量中。如果这个总结是准确的,请看一看。

评论太长了

一些意见:

  • 您的列,
    data.QW[,1]
    data.RS[,1]
    几乎肯定是影响因素
  • 这些因素几乎肯定有不同的水平集(其中一个因素可能有另一个因素的水平子集)。发生这种情况时,使用
    =
    进行比较将不起作用
  • 如果使用类似于
    read.csv(…)
    的方法将数据读入这些data.frames,则默认情况下,包含字符数据的任何列都会转换为因子。您可以通过在调用
    read.csv(…)
    中设置
    stringsAsFactors=FALSE
    来更改该行为。这是一个非常普遍的问题
  • 一旦您解决了因子/级别问题,就可以通过使用以下简单方法避免循环:
    data.QW[1:2000,1]==data.RW[1:2000,1]
    。这将创建一个长度为2000的向量,其中包含所有比较。不需要循环。当然,这假设两个data.frames都至少有2000行
  • 以下是第2项的示例:

    x <- as.factor(rep(LETTERS[1:5],3))   # has levels: A, B, C, D, E
    y <- as.factor(rep(LETTERS[1:3],5))   # has levels: A, B, C
    y==x
    # Error in Ops.factor(y, x) : level sets of factors are different
    

    x评论太长

    一些意见:

  • 您的列,
    data.QW[,1]
    data.RS[,1]
    几乎肯定是影响因素
  • 这些因素几乎肯定有不同的水平集(其中一个因素可能有另一个因素的水平子集)。发生这种情况时,使用
    =
    进行比较将不起作用
  • 如果使用类似于
    read.csv(…)
    的方法将数据读入这些data.frames,则默认情况下,包含字符数据的任何列都会转换为因子。您可以通过在调用
    read.csv(…)
    中设置
    stringsAsFactors=FALSE
    来更改该行为。这是一个非常普遍的问题
  • 一旦您解决了因子/级别问题,就可以通过使用以下简单方法避免循环:
    data.QW[1:2000,1]==data.RW[1:2000,1]
    。这将创建一个长度为2000的向量,其中包含所有比较。不需要循环。当然,这假设两个data.frames都至少有2000行
  • 以下是第2项的示例:

    x <- as.factor(rep(LETTERS[1:5],3))   # has levels: A, B, C, D, E
    y <- as.factor(rep(LETTERS[1:3],5))   # has levels: A, B, C
    y==x
    # Error in Ops.factor(y, x) : level sets of factors are different
    

    x下面的函数
    compare
    比较数据帧或矩阵
    a、b
    以查找
    b
    a
    的行匹配。它返回
    b
    中匹配的第一行位置(在需要进行一些内部排序以加速思考之后)。
    a
    中与
    b
    中不匹配的行的返回值为
    0
    。应处理数字、字符和因子列类型及其混合(后者仅适用于
    data.frames
    )。检查函数定义下面的示例

    compare<-function(a,b){
    
        #################################################
        if(dim(a)[2]!=dim(b)[2]){
            stop("\n Matrices a and b have different number of columns!")
        }
        if(!all(sapply(a, class)==sapply(b, class))){
            stop("\n Matrices a and b have incomparable column data types!")    
        }
        #################################################
        if(is.data.frame(a)){
            i <- sapply(a, is.factor)
            a[i] <- lapply(a[i], as.character)
        }
        if(is.data.frame(b)){
            i <- sapply(b, is.factor)
            b[i] <- lapply(b[i], as.character)
        }
        len1<-dim(a)[1]
        len2<-dim(b)[1]
        ord1<-do.call(order,as.data.frame(a))
        a<-a[ord1,]
        ord2<-do.call(order,as.data.frame(b))
        b<-b[ord2,]     
        #################################################
        found<-rep(0,len1)  
        dims<-dim(a)[2]
        do_dims<-c(1:dim(a)[2]) 
        at<-1
        for(i in 1:len1){
            for(m in do_dims){
                while(b[at,m]<a[i,m]){
                    at<-(at+1)      
                    if(at>len2){break}              
                }
                if(at>len2){break}
                if(b[at,m]>a[i,m]){break}
                if(m==dims){found[i]<-at}
            }
            if(at>len2){break}
        }
        #################################################
        found<-found[order(ord1)]
        found<-ord2[found]
        return(found)
    
    }
    # example data sets:
    ncols<-10
    nrows<-1E4
    a <- matrix(sample(LETTERS,size = (ncols*nrows), replace = T), ncol = ncols, nrow = nrows)
    b <- matrix(sample(LETTERS,size = (ncols*nrows), replace = T), ncol = ncols, nrow = nrows)
    b <- rbind(a,b) # example of b containing a
    b <- b[sample(dim(b)[1],dim(b)[1],replace = F),] 
    found<-compare(a,b)
    
    a<-as.data.frame(a) # = conversion to factors
    b<-as.data.frame(b) # = conversion to factors
    found<-compare(a,b)
    

    compare下面的函数
    compare
    比较数据帧或矩阵
    a、b
    以查找
    b
    a
    的行匹配。它返回
    b
    中匹配的第一行位置(在需要进行一些内部排序以加速思考之后)。
    a
    中与
    b
    中不匹配的行的返回值为
    0
    。应处理数字、字符和因子列类型及其混合(后者仅适用于
    data.frames
    )。检查函数定义下面的示例

    compare<-function(a,b){
    
        #################################################
        if(dim(a)[2]!=dim(b)[2]){
            stop("\n Matrices a and b have different number of columns!")
        }
        if(!all(sapply(a, class)==sapply(b, class))){
            stop("\n Matrices a and b have incomparable column data types!")    
        }
        #################################################
        if(is.data.frame(a)){
            i <- sapply(a, is.factor)
            a[i] <- lapply(a[i], as.character)
        }
        if(is.data.frame(b)){
            i <- sapply(b, is.factor)
            b[i] <- lapply(b[i], as.character)
        }
        len1<-dim(a)[1]
        len2<-dim(b)[1]
        ord1<-do.call(order,as.data.frame(a))
        a<-a[ord1,]
        ord2<-do.call(order,as.data.frame(b))
        b<-b[ord2,]     
        #################################################
        found<-rep(0,len1)  
        dims<-dim(a)[2]
        do_dims<-c(1:dim(a)[2]) 
        at<-1
        for(i in 1:len1){
            for(m in do_dims){
                while(b[at,m]<a[i,m]){
                    at<-(at+1)      
                    if(at>len2){break}              
                }
                if(at>len2){break}
                if(b[at,m]>a[i,m]){break}
                if(m==dims){found[i]<-at}
            }
            if(at>len2){break}
        }
        #################################################
        found<-found[order(ord1)]
        found<-ord2[found]
        return(found)
    
    }
    # example data sets:
    ncols<-10
    nrows<-1E4
    a <- matrix(sample(LETTERS,size = (ncols*nrows), replace = T), ncol = ncols, nrow = nrows)
    b <- matrix(sample(LETTERS,size = (ncols*nrows), replace = T), ncol = ncols, nrow = nrows)
    b <- rbind(a,b) # example of b containing a
    b <- b[sample(dim(b)[1],dim(b)[1],replace = F),] 
    found<-compare(a,b)
    
    a<-as.data.frame(a) # = conversion to factors
    b<-as.data.frame(b) # = conversion to factors
    found<-compare(a,b)
    

    compare您可以查看
    merge
    -您可以设置
    all=TRUE
    来合并数据帧并用NA填充缺少的值,或者
    match
    更合适。此外,该矩阵中包含哪些类型的数据?这些解决方案依赖于它是某种独特的值。这将起作用,除非我不确定缺失的值在哪里。一个数据框中可能缺少一行。一个位置中可能缺少一行,另一行中可能缺少另一行,以此类推。只有一行正在进行比较(第1行),因此我不是您的意思。标题中说您正在比较两列。但这不是您的循环所做的。它正在比较第1行和第1列到2000列。我的水晶球坏了。您可以发布
    dput(head(data.QW))
    data.RS的相同内容吗?您可以查看
    merge
    -您可以设置
    all=TRUE
    来合并数据。框架并用NA填充缺少的值,或者
    match
    更合适。此外,该矩阵中包含哪些类型的数据?这些解决方案依赖于它是某种独特的值。这将起作用,除非我不确定缺失的值在哪里。一个数据框中可能缺少一行。一个位置中可能缺少一行,另一行中可能缺少另一行,等等。只有一行正在进行比较(第1行),所以我不是你的意思。标题上说你是compa