根据同一df中的另一列将值分配给df $列

时间:2012-10-04 22:50:15

标签: r

df2 <- data.frame(Mean = c(.5,4,2.3,1.2,3.7,3.3,.8), Numbers = "NA")


for(i in 1:length(df2$Mean)){
        if(df2$Mean[i] <= .5) {
        df2$Number[i] = 0
        }           
        else if(df2$Mean[i] > .5 & df2$Mean[i] < 1.5){
        df2$Number[i] = 1
        }
        else if(df2$Mean[i] > 1.5 & df2$Mean[i] < 2.5){
        df2$Number[i] = 2
        }
        else if(df2$Mean[i] > 2.5 & df2$Mean[i] < 3.5){
        df2$Number[i] = 3
        }
        else {
        df2$Number[i] = 4
        }
    }

这个有效!但是当我尝试用它来创建一个函数并调用它时它不起作用。我将函数文件保存为“df2type.txt”:

type <- function(df2){
for(i in 1:length(df2$Mean)){
        if(df2$Mean[i] <= .5) {
        df2$Number[i] = 0
        }
        else if(df2$Mean[i] > .5 & df2$Mean[i] < 1.5){
        df2$Number[i] = 1
        }
        else if(df2$Mean[i] > 1.5 & df2$Mean[i] < 2.5){
        df2$Number[i] = 2
        }
        else if(df2$Mean[i] > 2.5 & df2$Mean[i] < 3.5){
        df2$Number[i] = 3
        }
        else {
        df2$Number[i] = 4
        }
}
}

我将函数调用为:

source("df2type.txt")
type(df2)

你能告诉我为什么功能不起作用吗?

非常感谢你!

2 个答案:

答案 0 :(得分:4)

df$Number <- findInterval( df$Mean, c( seq(0.5, 3.5, by=1) , Inf) )

有一个边缘情况,df $ Mean = 3.5,你的定义没有涵盖。我的方法给它一个4。

findInterval函数实际上正在执行与cut函数非常相似的操作,除了它返回一个数值而不是一个因子。它设置了一系列间隔,并告诉您每个项目将落入哪个区间。

答案 1 :(得分:4)

genotype更改了函数中存在的AllSamples副本。当此函数结束时,该内部副本将被销毁(以及对其的更改);它的原始版本(在您的全局工作空间中,最有可能)保持不变。如果你让函数返回AllSamples然后用返回值覆盖原始函数,那就可以了。

genotype <- function (AllSamples){
    for(i in 1:length(AllSamples$Mean.Regression)){
        ...
    }
    AllSamples
}

然后它会被称为

AllSamples <- genotype(AllSamples)

更惯用的方法是不更改genotype中的data.frame,而只是创建新列(作为向量),返回该列,并将其分配给{{1}列。 }。

AllSamples

将被称为

genotype <- function (AllSamples){
    CopyNumber <- rep(0, length(AllSamples$Mean.Regression))
    for(i in seq_along(AllSamples$Mean.Regression)){
        if(AllSamples$Mean.Regression[i] < .5) {
            CopyNumber[i] <- 0
        } else if(AllSamples$Mean.Regression[i] > .5 & AllSamples$Mean.Regression[i] < 1.5) {
            CopyNumber[i] <- 1
        } else if(AllSamples$Mean.Regression[i] > 1.5 & AllSamples$Mean.Regression[i] < 2.5) {
            CopyNumber[i] <- 2
        } else if(AllSamples$Mean.Regression[i] > 2.5 & AllSamples$Mean.Regression[i] < 3.5) {
            CopyNumber[i] <- 3
        } else {
            CopyNumber[i] <- 4
        }
    }
    CopyNumber
}   

真正的,真实的方法是使用矢量化函数而不是显式循环。

AllSamples$CopyNumber <- genotype(AllSamples)

你称之为

genotype <- function(AllSamples) {
    cut(AllSamples$Mean.Regression,
        breaks = c(-Inf, 0.5, 1.5, 2.5, 3.5, Inf),
        labels = FALSE) - 1
}
相关问题