2013-01-15 35 views
5

我想通過在值列表上使用apply的某種風格和爲每個值返回單行數據幀的函數逐行生成數據幀。作爲玩具的例子,假設我的值是i = 1:3,我還擁有:如何使用apply來逐行生成數據幀?

f <- function(i) { 
    return(data.frame(img=letters[i], cached=F, i=i, stringsAsFactors=F)) 
} 

我一直在sapplylapply,一堆轉等,但沒有成功(例如,d = sapply(1:3, f)看起來很有希望亂搞,但似乎是我想要的轉置,所以我試過d = t(sapply(1:3,f)),除了它是一個矩陣;因此我嘗試下一個d = as.data.frame(t(sapply(1:3, f))),其中出現正確(它打印出來就像我想要的),但仍然是錯誤的,因爲你會發現是否嘗試將其子集,例如d[,1]這實際上是一個列表)。

最後我得到了這一點,其工作原理:

d = apply(data.frame(i=1:3), 2, f)$i 

這給了我想要的框架:

img cached i 
1 a FALSE 1 
2 b FALSE 2 
3 c FALSE 3 

是否有表達上述更好/更清潔的方式?這一切都感覺很糟糕,對我來說過於複雜。


編輯:正如一些讀者提到,這個「玩具榜樣」是admitedly過於簡單,事實上只是f(1:3)會做什麼,它看起來像我請求。實際功能是基於網絡的指標儀表板的一部分,從各種數據庫表中提取數據,並製作我打算緩存的中等複雜圖(大部分時間它們變化相對較慢)。我想,相關的部分是該函數通常需要幾個參數,而這些參數不是一個簡單的序列1:n。所以,讓我重寫的例子是一點點更現實:

library(digest) 
gkey <- function(...) { 
    args <- list(...) 
    return(digest(paste(args,sep=".",collapse="."))); 
} 

f <- function(conn, table, checknew.query, plot.query, plot.fun, params) { 
    latest.data = queryExec(conn, table, checknew.query, params) 
    key = gkey(table, latest.data, plot.query, plot.fun, params) 
    out = getFromCacheOrPlot(key, conn, table, plot.query, plot.fun, params) 
    return(out) 
} 

其中queryExec建立一個查詢,執行它並檢索結果,gkey()計算基於其參數的哈希鍵,getFromCacheOrPlot()使用key建設一個文件名(.png圖像),如果它存在,則從緩存中檢索,否則生成它。它還返回一個data.frame,其中一行給我們文件名,一個html <img=...> blurb來顯示它,無論該圖是在緩存中還是在緩存中,以及哪些參數用於該圖。

所有這些都用於wiki系統的插件,並且某些頁面有十幾個圖或更多。

+3

'做。 call(rbind,lapply(i,f))'會做你在問什麼......但data.frame(img = letters [i],cached = F,i = i,stringsAsFactors = F)'' ...所以我想我不確定你在問什麼。 – Justin

+0

我認爲你需要更準確地代表你真正的問題,因爲我的直接反應是簡單地做'data.frame(IMG =字母[I],緩存=代表(FALSE,長度(i))的玩具例子,我=我)',我猜這不是你想要的。 – joran

+0

或者,因爲你已經取得的函數'F':'F(I)'會產生data.frame了。 – Justin

回答

8

do.call(rbind, lapply(i, f))會做什麼你問...但這樣會:

data.frame(img=letters[i], cached=F, i=i, stringsAsFactors=F) 

正如:

f(i) 
+4

或者使用'plyr :: ldply(i,f)' – hadley

+0

我可能也是,Hadley,因爲我已經在使用plyr和ggplot遍歷代碼來生成實際的地塊... –

+0

巨大的幫助和優雅 –

3

這是怎麼回事?無需使用任何味道的apply功能

foo <- function(x){ 
    i <- seq_len(x) 
    data.frame(img=letters[i], cached=FALSE, i=i, stringsAsFactors=F) 
} 


    foo(5) 
    img cached i 
1 a FALSE 1 
2 b FALSE 2 
3 c FALSE 3 
4 d FALSE 4 
5 e FALSE 5 
+0

對不起,但它不是我所追求的。正如我在上面的評論中指出的,這個玩具的例子太簡單了。我將重述我的問題。 –