循环中的R变量名,get等等

时间:2015-06-29 15:58:07

标签: r loops for-loop

还是比较新的R.试图在循环中使用动态变量但遇到各种各样的问题。初始代码看起来像这样(但更大)

data.train$Pclass_F <- as.factor(data.train$Pclass)
data.test$Pclass_F <- as.factor(data.test$Pclass)

我正在尝试构建一个循环,想象这样的东西

datalist <- c("data.train", "data.test")
for (i in datalist){
  i$Pclass_F <- as.factor(i$Pclass)
}

哪个不起作用。一点研究表明,为了将字符串datalist转换为变量,我需要使用get函数。所以我的下一次尝试是

datalist <- c("data.train", "data.test")
for (i in datalist){
  get(i$Pclass_F) <- as.factor(get(i$Pclass))
}

仍然不起作用Error in i$Pclass : $ operator is invalid for atomic vectors。试图

datalist <- c("data.train", "data.test")
for (i in datalist){
  get(i)$Pclass_F <- as.factor(get(i)$Pclass)
}

仍然不起作用Error in get(i)$Pclass_F <- as.factor(get(i)$Pclass) : could not find function "get<-"。甚至尝试了

datalist <- c("data.train", "data.test")
for (i in datalist){
  get(i[Pclass_F]) <- as.factor(get(i[Pclass]))
}

仍然不起作用Error in get(i[Pclass]) : object 'Pclass' not found。试过的

datalist <- c("data.train", "data.test")
for (i in datalist){
  get(i)[Pclass_F] <- as.factor(get(i)[Pclass])
}

仍然不起作用Error in '[.data.frame'(get(i), Pclass) : object 'Pclass' not found

现在意识到我从未包含数据,所以没有人可以自己运行,只是为了表明它不是数据问题

> class(data.train$Pclass)
[1] "integer"
> class(data.test$Pclass)
[1] "integer"
> datalist
[1] "data.train" "data.test" 

1 个答案:

答案 0 :(得分:4)

您遇到的问题与R中处理数据框和大多数其他对象的方式有关。在许多编程语言中,对象是(或至少可以)通过引用传递给函数。在C ++中,如果我将指向对象的指针传递给操作该对象的函数,则会修改原始对象。这不是R中大部分工作的方式。

当像这样创建一个对象时:

x <- list(a = 5, b = 9)

然后像这样复制:

y <- x

最初yx将指向RAM中的同一对象。但是一旦y被修改,就会创建一个副本。因此,分配y$c <- 12x无效。

get()不会以一种可以修改的方式返回命名对象,而无需先将其分配给另一个变量(这意味着原始变量保持不变)。

在R中执行此操作的正确方法是将数据帧存储在已命名的list中。然后,您可以遍历列表并使用替换语法来更改列。

datalist <- list(data.train = data.train, data.test = data.test)
for (df in names(datalist)){
  datalist[[df]]$Pclass_F <- as.factor(datalist[[df]]$Pclass_F)
}

你也可以使用:

datalist <- setNames(lapply(list(data.train, data.test), function(data) {
  data$Pclass_Fb <- as.factor(data$Pclass_Fb)
  data
}), c("data.train", "data.test"))

这是使用lapply处理列表的每个成员,返回带有修改列的新列表。

理论上,你可以通过在全球环境中使用[[运算符来实现你最初想要做的事情,但这将是一种非常规的做事方式,并可能在以后引起混淆。