亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

從R中的循環內將ggplot對象存儲在列表中

從R中的循環內將ggplot對象存儲在列表中

蠱毒傳說 2019-11-29 14:32:21
我的問題與此相似。當我循環生成圖對象(在本例中為直方圖)時,似乎所有對象都被最新圖覆蓋。為了調試,在循環中,我正在打印索引和生成的圖,兩者均正確顯示。但是當我查看存儲在列表中的圖時,除了標簽外,它們都相同。(我正在使用多圖制作合成圖像,但是如果一次print (myplots[[1]]) 完成print(myplots[[4]])一次,則會得到相同的結果。)因為我已經有一個附加的數據框(與類似問題的發布者不同),所以我不確定如何解決該問題。(順便說一句,列類是我在此處近似的原始數據集中的因子,但是如果它們是整數,則會發生相同的問題)這是一個可重現的示例:library(ggplot2)source("http://peterhaschke.com/Code/multiplot.R") #load multiplot function#make sample datacol1 <- c(2, 4, 1, 2, 5, 1, 2, 0, 1, 4, 4, 3, 5, 2, 4, 3, 3, 6, 5, 3, 6, 4, 3, 4, 4, 3, 4,           2, 4, 3, 3, 5, 3, 5, 5, 0, 0, 3, 3, 6, 5, 4, 4, 1, 3, 3, 2, 0, 5, 3, 6, 6, 2, 3,           3, 1, 5, 3, 4, 6)col2 <- c(2, 4, 4, 0, 4, 4, 4, 4, 1, 4, 4, 3, 5, 0, 4, 5, 3, 6, 5, 3, 6, 4, 4, 2, 4, 4, 4,           1, 1, 2, 2, 3, 3, 5, 0, 3, 4, 2, 4, 5, 5, 4, 4, 2, 3, 5, 2, 6, 5, 2, 4, 6, 3, 3,           3, 1, 4, 3, 5, 4)col3 <- c(2, 5, 4, 1, 4, 2, 3, 0, 1, 3, 4, 2, 5, 1, 4, 3, 4, 6, 3, 4, 6, 4, 1, 3, 5, 4, 3,           2, 1, 3, 2, 2, 2, 4, 0, 1, 4, 4, 3, 5, 3, 2, 5, 2, 3, 3, 4, 2, 4, 2, 4, 5, 1, 3,           3, 3, 4, 3, 5, 4)col4 <- c(2, 5, 2, 1, 4, 1, 3, 4, 1, 3, 5, 2, 4, 3, 5, 3, 4, 6, 3, 4, 6, 4, 3, 2, 5, 5, 4,          2, 3, 2, 2, 3, 3, 4, 0, 1, 4, 3, 3, 5, 4, 4, 4, 3, 3, 5, 4, 3, 5, 3, 6, 6, 4, 2,           3, 3, 4, 4, 4, 6)data2 <- data.frame(col1,col2,col3,col4)data2[,1:4] <- lapply(data2[,1:4], as.factor)colnames(data2)<- c("A","B","C", "D")#generate plotsmyplots <- list()  # new empty listfor (i in 1:4) {  p1 <- ggplot(data=data.frame(data2),aes(x=data2[ ,i]))+     geom_histogram(fill="lightgreen") +    xlab(colnames(data2)[ i])  print(i)  print(p1)  myplots[[i]] <- p1  # add each plot into plot list}multiplot(plotlist = myplots, cols = 4)當我在圖列表中查看圖對象的摘要時,這就是我看到的> summary(myplots[[1]])data: A, B, C, D [60x4]mapping:  x = data2[, i]faceting: facet_null() -----------------------------------geom_histogram: fill = lightgreen stat_bin:  position_stack: (width = NULL, height = NULL)我認為這mapping:  x = data2[, i]是問題所在,但我很沮喪!我無法發布圖片,因此如果我對問題的解釋令人困惑,則需要運行我的示例并查看圖表。謝謝!
查看完整描述

3 回答

?
三國紛爭

TA貢獻1804條經驗 獲得超7個贊

除了其他出色的答案之外,這里還有一個使用看起來“正?!钡脑u估而不是的解決方案eval。由于for循環沒有單獨的變量范圍(即,它們在當前環境中執行),因此我們需要使用它local來包裝for塊;此外,我們需要創建i一個局部變量-我們可以通過將其重新分配為其自己的名稱1來做到這一點:


myplots <- vector('list', ncol(data2))


for (i in seq_along(data2)) {

    message(i)

    myplots[[i]] <- local({

        i <- i

        p1 <- ggplot(data2, aes(x = data2[[i]])) +

            geom_histogram(fill = "lightgreen") +

            xlab(colnames(data2)[i])

        print(p1)

    })

}

但是,完全干凈的方法是for完全放棄循環,并使用列表函數生成結果。這可以通過幾種可能的方式工作。我認為以下是最簡單的方法:


plot_data_column = function (data, column) {

    ggplot(data, aes_string(x = column)) +

        geom_histogram(fill = "lightgreen") +

        xlab(column)

}


myplots <- lapply(colnames(data2), plot_data_column, data = data2)

這有幾個優點:更簡單,并且不會使環境混亂(使用loop變量i)。


1這看起來似乎令人困惑:為什么根本i <- i沒有效果?—因為執行分配,所以我們創建了一個新的局部變量,其名稱與外部作用域中的變量相同。我們同樣可以使用其他名稱,例如local_i <- i。


查看完整回答
反對 回復 2019-11-29
?
小怪獸愛吃肉

TA貢獻1852條經驗 獲得超1個贊

由于所有傳遞的表達式都被引用,因此i在循環結束時求值的那是i當時發生的一切,這是它的最終值。您可以通過eval(substitute(在每次迭代中輸入正確的值來解決此問題。


myplots <- list()  # new empty list

for (i in 1:4) {

    p1 <- eval(substitute(

        ggplot(data=data.frame(data2),aes(x=data2[ ,i]))+ 

          geom_histogram(fill="lightgreen") +

          xlab(colnames(data2)[ i])

    ,list(i = i)))

    print(i)

    print(p1)

    myplots[[i]] <- p1  # add each plot into plot list

}

multiplot(plotlist = myplots, cols = 4)


查看完整回答
反對 回復 2019-11-29
?
翻閱古今

TA貢獻1780條經驗 獲得超5個贊

擁有很多非常大的地塊是一個問題,而這兩種解決方案都不是。一種常見的解決方案是對您繪制的數據點數進行二次采樣(通常,這樣的大圖無論如何都無法可靠地顯示所有單獨的數據點),或者在繪制之前計算匯總統計信息(并繪制這些而不是原始數據)。但有時兩者都不起作用。在這種情況下,唯一的解決方案是避免一次在內存中包含多個圖。

查看完整回答
反對 回復 2019-11-29
  • 3 回答
  • 0 關注
  • 2783 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號