如何将函数应用于多列?

时间:2017-07-06 06:05:24

标签: r

对于以下数据集,我编写了一个函数

expconvert <- function(a) {
     if(a=="h" || a=="H")
         return(100)
     if(a=="k" || a=="K")
         return(1000)
     if(a=="m" || a=="M") 
         return(1000000)
     if(a=="b" || a=="B")
         return(1000000000)
     if(is.numeric(a))
         return(a)
     else
         return(0)
}

数据集如下所示,

CROPDMGEXP CROPDMG PROPDMG PROPDMGEXP
   k         0       20        h
   H         23      41        B
   k         10      5         B  
             2       3         k 
             5       50         

转换后的数据集如下所示,

CROPDMGEXP CROPDMG PROPDMG PROPDMGEXP
   1000        0       20        100
   100         23      41        1000000000
   1000        10      5         1000000000  
   0           2       3         1000 
   0           5       50        0 

我希望将上述功能应用于第一列和最后一列。当我编写以下代码时,请将df视为上述数据框

df[c(1,4)] <- apply(df[c(1,4)], MARGIN = 1, FUN = expconvert)

我没有得到所需的输出,即将这些列中的字母转换为适当的数字权重。

但是当我对单个列使用apply时,它可以正常工作,

df$CROPDMGEXP <- apply(df[1], MARGIN = 1, FUN = expconvert)

请帮助我如何同时将它应用于这两列。

数据集中有许多级别,因此当少数时,setNames很酷。这就是我写这个函数的原因。问题是该函数适用于带有apply的单列,但是当与带有apply的多列一起使用时返回错误的值。

1 个答案:

答案 0 :(得分:2)

我们可以使用lapply代替apply,因为lapply保持列的相同结构,而apply将转换为matrix和{{1}只能有一个matrix

class

此外,不是使用df[c(1, 4)] <- lapply(df[c(1, 4)], expconvert) ,而是可以轻松完成

if/else

数据

v1 <- setNames(c(100, 1000, 1000000, 1000000000), c('h', 'k', 'm', 'b'))
df[c(1, 4)] <- lapply(df[c(1, 4)], function(x) v1[tolower(x)])
df[is.na(df)] <- 0
df
#   CROPDMGEXP CROPDMG PROPDMG PROPDMGEXP
#1       1000       0      20        100
#2        100      23      41 1000000000
#3       1000      10       5 1000000000
#4          0       2       3       1000
#5          0       5      50          0