我希望能够使用for()
循环来自动执行在修改它们的许多变量上运行的相同操作。
这是最简单的设计示例:
varToChange = list( 1:10, iris$Species[1:10], letters[1:10]) # assume that it has many more than just 3 elements
varToChange
for (i in varToChange ) {
if (is.character(y)) i <- as.integer(as.ordered(i))
if (is.factor(y)) i <- as.integer(i)
}
varToChange # <-- Here I want to see my elements as integers now
这是让我回答这个问题的实际例子 - 来自:Best way to plot automatically all data.table columns using ggplot2
在以下功能中
f <- function(dt, x,y,k) {
if (is.numeric(x)) x <- names(dt)[x]
if (is.numeric(y)) y <- names(dt)[y]
if (is.numeric(k)) k <- names(dt)[k]
ggplot(dt, aes_string(x,y, col=k)) + geom_jitter(alpha=0.1)
}
f(diamonds, 1,7,2)
而不是像程序员那样残酷地重复相同的行,我宁愿有一个循环来为我重复这一行。 像这样的东西:
for (i in c(x,y,k)) {
if (is.numeric(i)) i <- names(dt)[i]
}
在C / C ++中,这可以使用指针完成。在R - 这一切都可能吗?
更新:非常好的想法使用下面的地图。但是它不适用于此示例
getColName <- function(dt, x) {
if (is.numeric(x)) {
x <- names(dt)[x]
}
x
}
f<- function(dt, x,y,k) {
list(x,y,k) <- Map(getColName, list(x,y,k), dt)
# if (is.numeric(x)) x <- names(dt)[x]
# if (is.numeric(y)) y <- names(dt)[y]
# if (is.numeric(k)) k <- names(dt)[k]
ggplot(dt, aes_string(x,y, col=k)) + geom_jitter(alpha=0.1)
}
f(diamonds, 1,7,2) # Brrr..
答案 0 :(得分:3)
不需要for循环,只需在每个列表项上映射一个函数
varToChange = list( 1:10, iris$Species[1:10], letters[1:10])
myfun <- function(y) {
if (is.character(y)) y <- as.integer(as.ordered(y))
if (is.factor(y)) y <- as.integer(y)
y
}
varToChange <- Map(myfun, varToChange)
UPDATE:Map永远不会修改变量,这在R中完成。使用Map返回的新值
f<- function(dt, x, y, k) {
args <- Map(function(x) getColName(dt, x), list(x=x,y=y,k=k))
ggplot(dt, aes_string(args$x,args$y, col=args$k)) + geom_jitter(alpha=0.1)
}
f(diamonds, 1,7,2)
答案 1 :(得分:1)
R中有两种迭代选择,迭代变量本身或索引。我通常建议迭代索引。这个案例说明了一个很大的优势,因为如果你使用索引,你的问题就不是问题了。
varToChange = list( 1:10, iris$Species[1:10], letters[1:10])
for (i in seq_along(varToChange)) {
if (is.character(varToChange[[i]])) varToChange[[i]] <- as.integer(as.factor(varToChange[[i]]))
if (is.factor(varToChange[[i]])) varToChange[[i]] <- as.integer(varToChange[[i]])
}
我还将as.ordered()
替换为as.factor()
- 有序因子和常规因子之间的唯一区别是建模中使用的默认对比。因为你只是强迫整数,所以并不重要。