我相当确定这是一个非常明显的问题,但我无法弄明白。
假设我有以下数据集:
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语句是如何工作的?
答案 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