有条件地创建一个新列

时间:2013-06-27 09:50:55

标签: r if-statement dataframe

我相当确定这是一个非常明显的问题,但我无法弄明白。

假设我有以下数据集:

test <- data.frame(A = c(1:10),
              B = c(1:10), C = c(1:10),
              P = c(1:10))

我想测试,如果有一个名为“P”的列,则创建一个名为“Z”的新列,并在其中放入一些从P计算的内容。

我编写了以下代码(只是为了尝试让它有条件地创建列,我还没试过让它做任何事情!):

Clean <- function(data) {
  if("P" %in% colnames(data)) {        
    data$Z <- NA
      }
  else {
    cat("doobedooo")
      }
    }
Clean(test)

但它似乎没有做任何事情,我不明白为什么,只需在数据集上运行test$Z <- NA就行了。 我把“doobedooo”放在那里,看看它是否在第一个条件下返回假。它似乎没有这样做。

我是否只是误解了if语句是如何工作的?

3 个答案:

答案 0 :(得分:4)

您必须从函数返回一个值,然后将该值赋给对象。与许多其他语言不同,R不会就地修改对象,至少在没有大量工作的情况下也是如此。

Clean <- function(data) {
    if("P" %in% colnames(data)) {        
        data$Z <- NA
    } else {
        cat("doobedooo"
    }
    return(data)
}
test <- Clean(test)

答案 1 :(得分:1)

@HongOi答案是您问题的直接答案。我是处理问题的R方式。由于您要创建其他列的其他列组合,因此您可以使用transform(或within),例如:

if('P' %in% colnames(test))
     test <- transform(test,Z={## you can put any statement here
                               x=P+1
                               x^2
                               round(x/12,2)
                             }
                          )

 head(test)
  A B C P    Z
1 1 1 1 1 0.17
2 2 2 2 2 0.25
3 3 3 3 3 0.33
4 4 4 4 4 0.42
5 5 5 5 5 0.50
6 6 6 6 6 0.58

答案 2 :(得分:0)

以前的答案已经提供了您需要的一切。但是,还有另一种方法可以解决这些问题。在R中,您可以使用environment通过引用设置和添加数据,而不是返回()整个表格(即使您更改了一部分)。

env <- new.env()
env$test <- test

system.time({
Clean <- function(data) {
  if("P" %in% names(data$test)) {        
    data$test$Z <- NA
  }
  else {
    cat("doobedooo")
  }
}
Clean(env)
})

> env$test
    A  B  C  P  Z
1   1  1  1  1 NA
2   2  2  2  2 NA
3   3  3  3  3 NA
4   4  4  4  4 NA
5   5  5  5  5 NA
6   6  6  6  6 NA
7   7  7  7  7 NA
8   8  8  8  8 NA
9   9  9  9  9 NA
10 10 10 10 10 NA