1

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

假设我有以下数据集:

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在数据集上运行时确实有效。我把“doobedoo”放在那里,看看它是否在第一个条件下返回错误。它似乎没有这样做。

我是否只是误解了 if 语句的工作原理?

4

3 回答 3

4

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

Clean <- function(data) {
    if("P" %in% colnames(data)) {        
        data$Z <- NA
    } else {
        cat("doobedooo"
    }
    return(data)
}
test <- Clean(test)
于 2013-06-27T09:55:02.377 回答
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
于 2013-06-27T10:27:03.700 回答
0

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

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
于 2013-06-27T11:28:39.117 回答