2015-06-17 42 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,可以在阵列上运行(不只是一个列表)