2015-10-30 152 views
0

我有以下數據框架,我想用top_products中尚未出現在該行中的第一個product_id替換NA。爲了給出一些背景,這些是產品推薦。如何將函數應用於每一行並返回R中的行?

雖然我對plyr和sapply有一些經驗,但我正在努力找出實現這一目標的正確方法。

我認爲下面的代碼本身就說明了。

> head(recs_with_na) 
     V1 V2 V3 V4 
148 1227 1213 <NA> <NA> 
249 1169 1221 <NA> <NA> 
553 1227 1162 <NA> <NA> 
732 1227 1162 <NA> <NA> 
765 1227 1162 <NA> <NA> 
776 1227 1162 <NA> <NA> 
> top_products 
    product_id count 
21  1162 7917 
65  1213 4839 
19  1160 4799 
11  1152 3543 
34  1175 3423 
75  1227 2719 
2  1143 2396 
13  1154 2168 
> fill_nas_with_top <- function(data, top_products) { 
+ top_products_copy <- top_products 
+ mydata <- data 
+ #mydata <- as.data.frame(data) 
+ for (i in 1:4) { 
+  if (is.na(mydata[,i])) { 
+  mydata[,i] <- top_products_copy[1,1] 
+  top_products_copy <- top_products_copy[-1,]  
+  
+  } 
+  else { 
+  top_products_copy <- top_products_copy[top_products_copy[,1] != mydata[,i],] 
+  } 
+ } 
+ return(mydata) 
+ } 
> sapply(recs_with_na, fill_nas_with_top, top_products) 
Show Traceback 

Rerun with Debug 
Error in `[.default`(mydata, , i) : incorrect number of dimensions 
+1

recs_with_na的列被傳遞逐個添加到函數fill_nas_with_top。但是你想要一個接一個地傳遞行。 – cryptomanic

回答

1

R使用按值傳遞語義。每次調用函數時,您的函數將獲得副本數據和top_products,因此不需要您製作防禦副本。

因爲按值傳遞意味着要創建副本(也有其他許多原因),所以給你的函數儘可能少的信息來完成他們的任務是一個好習慣。在這種情況下,您不需要傳遞整個top_products數據框。 product_ids的向量將會執行。

fill_nas_with_top <- function(data, top) { 
    for (i in 1:4) { 
     d <- data[i] 
     if (is.na(d)) { 
      ## Find the first not already existing value 
      for (t in top) { 
       top <- top[-1] 
       if (!t %in% data) { 
        data[i] <- t 
        break; 
       } 
      } 
     } else { 
      # This no longer assumes that product_ids in top are ordered as in data 
      if (d %in% top) top <- top[-which(d == top)] 
     } 
    } 
    return(data) 
} 

這樣調用(注意,我們在top_products product_ids的矢量稱呼它):

as.data.frame(t(apply(recs_with_na, 1, fill_nas_with_top, top_products[,1])))

會產生:

V1 V2 V3 V4 
1 1227 1213 1162 1160 
2 1169 1221 1162 1213 
3 1227 1162 1213 1160 
4 1227 1162 1213 1160 
5 1227 1162 1213 1160 
6 1227 1162 1213 1160 
+0

有道理......我認爲你的其他陳述假設top_products按照與數據中的項目相同的順序排序,但事實並非如此。我試着用這段代碼替換你的if語句,但是我得到一個錯誤。另外,我修改了你的代碼,因爲數據是一個數據框而不是一個矢量,它看起來像你沒有引用一個特定的列。你應該如何在評論中粘貼代碼?使用pastebin?這是我的新代碼:http://pastebin.com/00iNZD1U – jwoww

+0

更正 - 我的意思是top_products是一個數據框架。 – jwoww

+0

@jwoww查看更新的答案。 – kliron

相關問題