对于以下数据集,我编写了一个函数
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的多列一起使用时返回错误的值。
答案 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