2015-06-17 40 views
1

我有一個數據集,我想根據其他一些列插入一個新列。R根據函數向數據集添加一列

我這樣做:

addGoodnessCustomerClass <- function(Amount, Age){ 
    if((Amount > 90)&& (Age > 23) && (Age < 44)) 
    return (c("VIP")) 
    return (c("BAD")) 
} 

cbind(cards, lapply(X = cards, FUN = addGoodnessCustomerClass(cards$Amount, cards$Age))) 

我收到錯誤消息:

Error in get(as.character(FUN), mode="function", envir = envir): 
object 'BAD' of mode 'function' was not found 

幫助,請

+1

爲什麼要退'C(「VIP」)'您的自定義功能?爲什麼不返回原始字符串? –

+0

@TimBiegeleisen我已經試過了,我得到了同樣的錯誤 –

+0

你試過使用'sapply()'嗎? –

回答

2

您可以使用行模式apply()功能(第二個參數設置爲1):

addGoodnessCustomerClass <- function(Amount, Age) { 
    if ((Amount > 90)&& (Age > 23) && (Age < 44)) 
     return ("VIP") 
    return ("BAD") 
} 

old.num.cols <- ncol(cards) # remember number of columns before cbind 
cbind(cards, apply(cards[,c('Amount','Age')], 
        1, 
        function(y) addGoodnessCustomerClass(y['Amount'],y['Age']))) 

要命名,你可以明確地設置像這樣的新列:

colnames(cards)[old.num.cols+1] <- "CustomerClass" 
+0

我無法運行第一行,這是'lapply',我得到了與我在問題 –

+0

中說過的完全相同的錯誤消息。使用'apply'就像我上面所說的那樣應該適合你。 –

+0

它的工作原理,謝謝,但'1'是什麼意思,再加上,我怎麼能給這個新添加的列添加一個名字? (接受的答案) –

2

我覺得你並不真的需要一個「功能」,而是一個測試,以確定新列。您可以通過撥打ifelse來完成此操作。這個怎麼樣:

cbind.data.frame(cards, AccountClass=cases("VIP"=cards$Amount > 90 & cards$Age > 23 & cards$Age < 44, "OKAY"=cards$Amount > 50 & cards$Age>30, "BAD"=TRUE) 

注意cbind.data.frame作爲cbind將返回一個矩陣,我猜你不想要。

+0

即使我向你展示了什麼看起來像一個if else,但實際上在我的真實代碼中,我有超過7個if語句,所以我真的需要一個分離的函數。 –

+0

@smci說這仍然是正確的設計。嘗試'memisc'包中的'cases'函數。即'案件( 「貴賓」=卡$金額> 90, 「OKAY」=卡$金額> 50,「壞」= TRUE)'看到之前SO張貼在這裏:http://stackoverflow.com/questions/4622060/case-statement-equivalent-in-r – cr1msonB1ade

+0

謝謝,但你仍然沒有使用'Age'變量,無論如何,我有一個答案,感謝您的幫助 –

0

我相信你的錯誤的根源在於以下(從lapply幫助頁面):

函數fun必須能夠接受作爲輸入的任何X的元素如果是後者原子矢量,FUN將始終通過同一類型的長度爲一個向量作爲X.

當調用lapply()上的數據幀,則問R鍵一些函數應用於數據幀中的每一列(其中當然這不是你的目標)。

通常在多個列進行操作,你反而要使用apply,可以在陣列上運行(不只是一個列表)