2017-06-13 63 views
0

我希望能夠使用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.. 

回答

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:地圖從來沒有就地修改變量,這簡直是不是在R中完成的。使用地圖返回的新值

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

對於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() - 有序因子和規則因素之間的唯一區別是在模型中使用的默認對比度。因爲你只是強迫整數,所以沒關係。