使用参数作为列名创建函数

时间:2018-10-09 21:17:26

标签: r

我正在尝试创建一个函数,该函数将一列的值与另一列的值进行成对比较,并根据这些值创建一个新的向量。我无法解决如何允许其中两个参数成为可以更改的列名,以及该函数可以在另一组列上使用的问题。 具体情况是,对于亲禽(pbc1 ... pbc4)有四列彩色条带标签,对于其雏鸟(obc1 ... obc4)有四列。带区列是字符列,例如“ G”,“ PG”,“ B”等。 这是我函数的第一部分的代码,我将在运行后将其扩展为包括所有成对比较:

colourdistance1 <- function(df, refcoldistdf, pbc, obc){
    n <- length(pbc)
    coldist1 <- rep(NA,n)
    for(i in 1:n){
        if(pbc[i]==obc[i]){
            coldist1[i] <- 0
         } else if(pbc[i]=='M'|obc[i]=='M'){
             coldist1[i] <- NA
         } else if(pbc[i]=='G'& obc[i]=='PG'| obc[i]=='G'& pbc[i]=='PG'){
             coldist1[i] <- refcoldistdf[2,2]
         } else {
             coldist1[i] <- NA
         }
    }
}

p1o1 <- colourdistance1(bd_df, refcoldistdf,pbc = pbc1, obc = obc1)

此调用仅将对象p1o1返回为NULL 我也尝试过:

colourdistance1 <- function(df, refcoldistdf, pbc, obc){
    n <- length(pbc)
    coldist1 <- rep(NA,n)
    for(i in 1:n){
        if(df$pbc[i]==df$obc[i]){
            coldist1[i] <- 0
        } else if(df$pbc[i]=='M'|df$obc[i]=='M'){
            coldist1[i] <- NA
        } else if(df$pbc[i]=='G'& df$obc[i]=='PG'| df$obc[i]=='G'& df$pbc[i]=='PG') { 
            coldist1[i] <- refcoldistdf[2,2]
        } else {
            coldist1[i] <- NA
        }
    }
}

但这只会产生此错误:

Error in if (df$pbc[i] == df$obc[i]) { : argument is of length zero

我已经尝试了函数外的所有代码,插入了列名,索引号和df名称,并且一切正常。这使我认为函数参数没有按我的意图连接到函数代码时遇到问题。 任何帮助将不胜感激!

可重复的测试数据:

pbc1 <- c('B','W','G','R')
obc1 <- c('Y','W','PG','FP')
pbc2 <- c('W','W','W','M')
obc2 <- c('M','W','R','R')
pbc3 <- c('W','K','FP','K')
obc3 <- c('G','PG','B','PB')
pbc4 <- c('K','K','B','M')
obc4 <- c('K','PG','W','M')
testbanddf <- cbind(pbc1,obc1,pbc2,obc2,pbc3,obc3,pbc4,obc4)
testrefcoldist <- diag(11)

1 个答案:

答案 0 :(得分:1)

因此,有很多注释,但是首先,您可以尝试以下操作:

pbc1 <- c('B','W','G','R')
obc1 <- c('Y','W','PG','FP')
pbc2 <- c('W','W','W','M')
obc2 <- c('M','W','R','R')
pbc3 <- c('W','K','FP','K')
obc3 <- c('G','PG','B','PB')
pbc4 <- c('K','K','B','M')
obc4 <- c('K','PG','W','M')
testbanddf <- data.frame(pbc1,obc1,pbc2,obc2,pbc3,obc3,pbc4,obc4)
testrefcoldist <- diag(11)

colourdistance1 <- function(df, refcoldistdf, pbc, obc){
    n <- nrow(df)
    coldist1 <- rep(NA,n)

    pbc <- df[[pbc]]
    obc <- df[[obc]]

    for(i in 1:n){
        if(pbc[i]==obc[i]){
            coldist1[i] <- 0
        } else if(pbc[i]=='M'|obc[i]=='M'){
            coldist1[i] <- NA
        } else if(pbc[i]=='G'& obc[i]=='PG'| obc[i]=='G'& pbc[i]=='PG'){
            coldist1[i] <- refcoldistdf[2,2]
        } else {
            coldist1[i] <- NA
        }
    }
    coldist1
}

colourdistance1(testbanddf, testrefcoldist,pbc = "pbc1", obc = "obc1")
  1. cbind()创建一个矩阵,而不是一个数据帧。您可以使用函数data.frame()创建数据帧。
  2. 最简单的方法是使参数pbcobc成为表示列名称的字符
  3. 使用$引用数据框列在进行交互工作时很有用,但在编写函数且事先不知道列名时却没有用(如您所见)。在这种情况下,您可以使用[[,并可以按名称或位置进行选择。
  4. 您编写的函数没有明确返回coldist1