2016-09-27 63 views
2

我想总结我数据框的最后2列中的整数数字。我找到了一个函数来进行求和,但我想我可能会遇到应用该函数的问题 - 不确定?在数据帧的特定列中计算数位总和

Dataframe 
a = c("a", "b", "c") 
b = c(1, 11, 2) 
c = c(2, 4, 23) 
data <- data.frame(a,b,c) 

#Digitsum function 
digitsum <- function(x) sum(floor(x/10^(0:(nchar(as.character(x)) - 1))) %% 10) 

#Applying function 
data[2:3] <- lapply(data[2:3], digitsum) 

这是错误,我得到:

*Warning messages: 
1: In 0:(nchar(as.character(x)) - 1) : 
    numerical expression has 3 elements: only the first used 
2: In 0:(nchar(as.character(x)) - 1) : 
    numerical expression has 3 elements: only the first used* 

回答

2

你此刻的功能digitsum工作正常,一个标输入,例如,

digitsum(32) 
# [1] 5 

但是,它可以不采取向量输入,否则":"会抱怨。你需要向量化这个功能,使用Vectorize

vec_digitsum <- Vectorize(digitsum) 

然后,它适用于一个向量输入:

b = c(1, 11, 2) 
vec_digitsum(b) 
# [1] 1 2 2 

现在你可以使用lapply无故障。

+0

干杯!有效!非常感激! – dsnOwhiskey

2

@Zheyuan Li的回答解决了您使用lapply的问题。虽然我想补充几点:

  • Vectorize只是与mapply的包装,它不会给你矢量化的性能。

  • 函数本身可以为更好的可读性得到改善:

看到

digitsum <- function(x) sum(floor(x/10^(0:(nchar(as.character(x)) - 1))) %% 10) 
vec_digitsum <- Vectorize(digitsum) 

sumdigits <- function(x){ 
    digits <- strsplit(as.character(x), "")[[1]] 
    sum(as.numeric(digits)) 
} 
vec_sumdigits <- Vectorize(sumdigits) 

microbenchmark::microbenchmark(digitsum(12324255231323), 
    sumdigits(12324255231323), times = 100) 

Unit: microseconds 
         expr min  lq  mean median  uq max neval cld 
    digitsum(12324255231323) 12.223 12.712 14.50613 13.201 13.690 96.801 100 a 
sumdigits(12324255231323) 13.689 14.667 15.32743 14.668 15.157 38.134 100 a 

两个版本的性能是相似的,但第二个是一个更容易理解。

有趣的是,Vectorize包装增加相当大的开销,用于单个输入:

microbenchmark::microbenchmark(vec_digitsum(12324255231323), 
    vec_sumdigits(12324255231323), times = 100) 

Unit: microseconds 
          expr min  lq  mean median  uq  max neval cld 
    vec_digitsum(12324255231323) 92.890 96.801 267.2665 100.223 108.045 16387.07 100 a 
vec_sumdigits(12324255231323) 94.357 98.757 106.2705 101.445 107.556 286.00 100 a 

此功能的另一个优点是,如果你在字符串格式有非常大的数字,它仍然可以工作(以除去小的修改as.character)。虽然第一个版本的函数会遇到大数目的问题,或者可能会引入错误。

注意:起初我的基准测试是比较OP函数的矢量化版本和我的函数的非矢量化版本,这给我错误的印象我的函数要快得多。原来是由Vectorize开销造成的。

+0

感谢队友,感谢您的帮助! – dsnOwhiskey