Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xuri
excelize
提交
6fa950a4
excelize
项目概览
xuri
/
excelize
通知
13
Star
2
Fork
4
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
excelize
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
已验证
提交
6fa950a4
编写于
4月 16, 2022
作者:
xurime
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ref #65, new formula functions: SKEW.P and SLOPE, remove no-required format default
上级
5a279321
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
160 addition
and
35 deletion
+160
-35
calc.go
calc.go
+60
-14
calc_test.go
calc_test.go
+97
-0
chart.go
chart.go
+1
-6
picture.go
picture.go
+0
-5
shape.go
shape.go
+1
-6
table.go
table.go
+1
-4
未找到文件。
calc.go
浏览文件 @
6fa950a4
...
...
@@ -640,7 +640,9 @@ type formulaFuncs struct {
// SIN
// SINH
// SKEW
// SKEW.P
// SLN
// SLOPE
// SMALL
// SQRT
// SQRTPI
...
...
@@ -8860,14 +8862,20 @@ func (fn *formulaFuncs) min(mina bool, argsList *list.List) formulaArg {
return
newNumberFormulaArg
(
min
)
}
// pearsonProduct is an implementation of the formula functions PEARSON
and
//
RSQ
.
// pearsonProduct is an implementation of the formula functions PEARSON
, RSQ
//
and SLOPE
.
func
(
fn
*
formulaFuncs
)
pearsonProduct
(
name
string
,
argsList
*
list
.
List
)
formulaArg
{
if
argsList
.
Len
()
!=
2
{
return
newErrorFormulaArg
(
formulaErrorVALUE
,
fmt
.
Sprintf
(
"%s requires 2 arguments"
,
name
))
}
array1
:=
argsList
.
Front
()
.
Value
.
(
formulaArg
)
.
ToList
()
array2
:=
argsList
.
Back
()
.
Value
.
(
formulaArg
)
.
ToList
()
var
array1
,
array2
[]
formulaArg
if
name
==
"SLOPE"
{
array1
=
argsList
.
Back
()
.
Value
.
(
formulaArg
)
.
ToList
()
array2
=
argsList
.
Front
()
.
Value
.
(
formulaArg
)
.
ToList
()
}
else
{
array1
=
argsList
.
Front
()
.
Value
.
(
formulaArg
)
.
ToList
()
array2
=
argsList
.
Back
()
.
Value
.
(
formulaArg
)
.
ToList
()
}
if
len
(
array1
)
!=
len
(
array2
)
{
return
newErrorFormulaArg
(
formulaErrorNA
,
formulaErrorNA
)
}
...
...
@@ -8898,7 +8906,10 @@ func (fn *formulaFuncs) pearsonProduct(name string, argsList *list.List) formula
if
name
==
"RSQ"
{
return
newNumberFormulaArg
(
math
.
Pow
(
sum
/
math
.
Sqrt
(
deltaX
*
deltaY
),
2
))
}
return
newNumberFormulaArg
(
sum
/
math
.
Sqrt
(
deltaX
*
deltaY
))
if
name
==
"PEARSON"
{
return
newNumberFormulaArg
(
sum
/
math
.
Sqrt
(
deltaX
*
deltaY
))
}
return
newNumberFormulaArg
(
sum
/
deltaX
)
}
// PEARSON function calculates the Pearson Product-Moment Correlation
...
...
@@ -9268,16 +9279,19 @@ func (fn *formulaFuncs) RSQ(argsList *list.List) formulaArg {
return
fn
.
pearsonProduct
(
"RSQ"
,
argsList
)
}
// SKEW function calculates the skewness of the distribution of a supplied set
// of values. The syntax of the function is:
//
// SKEW(number1,[number2],...)
//
func
(
fn
*
formulaFuncs
)
SKEW
(
argsList
*
list
.
List
)
formulaArg
{
// skew is an implementation of the formula functions SKEW and SKEW.P.
func
(
fn
*
formulaFuncs
)
skew
(
name
string
,
argsList
*
list
.
List
)
formulaArg
{
if
argsList
.
Len
()
<
1
{
return
newErrorFormulaArg
(
formulaErrorVALUE
,
"SKEW requires at least 1 argument"
)
return
newErrorFormulaArg
(
formulaErrorVALUE
,
fmt
.
Sprintf
(
"%s requires at least 1 argument"
,
name
))
}
mean
:=
fn
.
AVERAGE
(
argsList
)
var
stdDev
formulaArg
var
count
,
summer
float64
if
name
==
"SKEW"
{
stdDev
=
fn
.
STDEV
(
argsList
)
}
else
{
stdDev
=
fn
.
STDEVP
(
argsList
)
}
mean
,
stdDev
,
count
,
summer
:=
fn
.
AVERAGE
(
argsList
),
fn
.
STDEV
(
argsList
),
0.0
,
0.0
for
arg
:=
argsList
.
Front
();
arg
!=
nil
;
arg
=
arg
.
Next
()
{
token
:=
arg
.
Value
.
(
formulaArg
)
switch
token
.
Type
{
...
...
@@ -9300,11 +9314,43 @@ func (fn *formulaFuncs) SKEW(argsList *list.List) formulaArg {
}
}
if
count
>
2
{
return
newNumberFormulaArg
(
summer
*
(
count
/
((
count
-
1
)
*
(
count
-
2
))))
if
name
==
"SKEW"
{
return
newNumberFormulaArg
(
summer
*
(
count
/
((
count
-
1
)
*
(
count
-
2
))))
}
return
newNumberFormulaArg
(
summer
/
count
)
}
return
newErrorFormulaArg
(
formulaErrorDIV
,
formulaErrorDIV
)
}
// SKEW function calculates the skewness of the distribution of a supplied set
// of values. The syntax of the function is:
//
// SKEW(number1,[number2],...)
//
func
(
fn
*
formulaFuncs
)
SKEW
(
argsList
*
list
.
List
)
formulaArg
{
return
fn
.
skew
(
"SKEW"
,
argsList
)
}
// SKEWdotP function calculates the skewness of the distribution of a supplied
// set of values. The syntax of the function is:
//
// SKEW.P(number1,[number2],...)
//
func
(
fn
*
formulaFuncs
)
SKEWdotP
(
argsList
*
list
.
List
)
formulaArg
{
return
fn
.
skew
(
"SKEW.P"
,
argsList
)
}
// SLOPE returns the slope of the linear regression line through data points in
// known_y's and known_x's. The slope is the vertical distance divided by the
// horizontal distance between any two points on the line, which is the rate
// of change along the regression line. The syntax of the function is:
//
// SLOPE(known_y's,known_x's)
//
func
(
fn
*
formulaFuncs
)
SLOPE
(
argsList
*
list
.
List
)
formulaArg
{
return
fn
.
pearsonProduct
(
"SLOPE"
,
argsList
)
}
// SMALL function returns the k'th smallest value from an array of numeric
// values. The syntax of the function is:
//
...
...
calc_test.go
浏览文件 @
6fa950a4
...
...
@@ -1157,6 +1157,12 @@ func TestCalcCellValue(t *testing.T) {
"=SKEW(1,2,3,4,3)"
:
"-0.404796008910937"
,
"=SKEW(A1:B2)"
:
"0"
,
"=SKEW(A1:D3)"
:
"0"
,
// SKEW.P
"=SKEW.P(1,2,3,4,3)"
:
"-0.27154541788364"
,
"=SKEW.P(A1:B2)"
:
"0"
,
"=SKEW.P(A1:D3)"
:
"0"
,
// SLOPE
"=SLOPE(A1:A4,B1:B4)"
:
"1"
,
// SMALL
"=SMALL(A1:A5,1)"
:
"0"
,
"=SMALL(A1:B5,2)"
:
"1"
,
...
...
@@ -3063,6 +3069,14 @@ func TestCalcCellValue(t *testing.T) {
"=SKEW()"
:
"SKEW requires at least 1 argument"
,
"=SKEW(
\"\"
)"
:
"strconv.ParseFloat: parsing
\"\"
: invalid syntax"
,
"=SKEW(0)"
:
"#DIV/0!"
,
// SKEW.P
"=SKEW.P()"
:
"SKEW.P requires at least 1 argument"
,
"=SKEW.P(
\"\"
)"
:
"strconv.ParseFloat: parsing
\"\"
: invalid syntax"
,
"=SKEW.P(0)"
:
"#DIV/0!"
,
// SLOPE
"=SLOPE()"
:
"SLOPE requires 2 arguments"
,
"=SLOPE(A1:A2,B1:B1)"
:
"#N/A"
,
"=SLOPE(A4,A4)"
:
"#DIV/0!"
,
// SMALL
"=SMALL()"
:
"SMALL requires 2 arguments"
,
"=SMALL(A1:A5,0)"
:
"k should be > 0"
,
...
...
@@ -4968,6 +4982,89 @@ func TestCalcMODE(t *testing.T) {
}
}
func
TestCalcPEARSON
(
t
*
testing
.
T
)
{
cellData
:=
[][]
interface
{}{
{
"x"
,
"y"
},
{
1
,
10.11
},
{
2
,
22.9
},
{
2
,
27.61
},
{
3
,
27.61
},
{
4
,
11.15
},
{
5
,
31.08
},
{
6
,
37.9
},
{
7
,
33.49
},
{
8
,
21.05
},
{
9
,
27.01
},
{
10
,
45.78
},
{
11
,
31.32
},
{
12
,
50.57
},
{
13
,
45.48
},
{
14
,
40.94
},
{
15
,
53.76
},
{
16
,
36.18
},
{
17
,
49.77
},
{
18
,
55.66
},
{
19
,
63.83
},
{
20
,
63.6
},
}
f
:=
prepareCalcData
(
cellData
)
formulaList
:=
map
[
string
]
string
{
"=PEARSON(A2:A22,B2:B22)"
:
"0.864129542184994"
,
}
for
formula
,
expected
:=
range
formulaList
{
assert
.
NoError
(
t
,
f
.
SetCellFormula
(
"Sheet1"
,
"C1"
,
formula
))
result
,
err
:=
f
.
CalcCellValue
(
"Sheet1"
,
"C1"
)
assert
.
NoError
(
t
,
err
,
formula
)
assert
.
Equal
(
t
,
expected
,
result
,
formula
)
}
}
func
TestCalcRSQ
(
t
*
testing
.
T
)
{
cellData
:=
[][]
interface
{}{
{
"known_y's"
,
"known_x's"
},
{
2
,
22.9
},
{
7
,
33.49
},
{
8
,
34.5
},
{
3
,
27.61
},
{
4
,
19.5
},
{
1
,
10.11
},
{
6
,
37.9
},
{
5
,
31.08
},
}
f
:=
prepareCalcData
(
cellData
)
formulaList
:=
map
[
string
]
string
{
"=RSQ(A2:A9,B2:B9)"
:
"0.711666290486784"
,
}
for
formula
,
expected
:=
range
formulaList
{
assert
.
NoError
(
t
,
f
.
SetCellFormula
(
"Sheet1"
,
"C1"
,
formula
))
result
,
err
:=
f
.
CalcCellValue
(
"Sheet1"
,
"C1"
)
assert
.
NoError
(
t
,
err
,
formula
)
assert
.
Equal
(
t
,
expected
,
result
,
formula
)
}
}
func
TestCalcSLOP
(
t
*
testing
.
T
)
{
cellData
:=
[][]
interface
{}{
{
"known_x's"
,
"known_y's"
},
{
1
,
3
},
{
2
,
7
},
{
3
,
17
},
{
4
,
20
},
{
5
,
20
},
{
6
,
27
},
}
f
:=
prepareCalcData
(
cellData
)
formulaList
:=
map
[
string
]
string
{
"=SLOPE(A2:A7,B2:B7)"
:
"0.200826446280992"
,
}
for
formula
,
expected
:=
range
formulaList
{
assert
.
NoError
(
t
,
f
.
SetCellFormula
(
"Sheet1"
,
"C1"
,
formula
))
result
,
err
:=
f
.
CalcCellValue
(
"Sheet1"
,
"C1"
)
assert
.
NoError
(
t
,
err
,
formula
)
assert
.
Equal
(
t
,
expected
,
result
,
formula
)
}
}
func
TestCalcSHEET
(
t
*
testing
.
T
)
{
f
:=
NewFile
()
f
.
NewSheet
(
"Sheet2"
)
...
...
chart.go
浏览文件 @
6fa950a4
...
...
@@ -479,16 +479,11 @@ func parseFormatChartSet(formatSet string) (*formatChart, error) {
},
Format
:
formatPicture
{
FPrintsWithSheet
:
true
,
FLocksWithSheet
:
false
,
NoChangeAspect
:
false
,
OffsetX
:
0
,
OffsetY
:
0
,
XScale
:
1.0
,
YScale
:
1.0
,
},
Legend
:
formatChartLegend
{
Position
:
"bottom"
,
ShowLegendKey
:
false
,
Position
:
"bottom"
,
},
Title
:
formatChartTitle
{
Name
:
" "
,
...
...
picture.go
浏览文件 @
6fa950a4
...
...
@@ -31,11 +31,6 @@ import (
func
parseFormatPictureSet
(
formatSet
string
)
(
*
formatPicture
,
error
)
{
format
:=
formatPicture
{
FPrintsWithSheet
:
true
,
FLocksWithSheet
:
false
,
NoChangeAspect
:
false
,
Autofit
:
false
,
OffsetX
:
0
,
OffsetY
:
0
,
XScale
:
1.0
,
YScale
:
1.0
,
}
...
...
shape.go
浏览文件 @
6fa950a4
...
...
@@ -25,15 +25,10 @@ func parseFormatShapeSet(formatSet string) (*formatShape, error) {
Height
:
160
,
Format
:
formatPicture
{
FPrintsWithSheet
:
true
,
FLocksWithSheet
:
false
,
NoChangeAspect
:
false
,
OffsetX
:
0
,
OffsetY
:
0
,
XScale
:
1.0
,
YScale
:
1.0
,
},
Line
:
formatLine
{
Width
:
1
},
Macro
:
""
,
Line
:
formatLine
{
Width
:
1
},
}
err
:=
json
.
Unmarshal
([]
byte
(
formatSet
),
&
format
)
return
&
format
,
err
...
...
table.go
浏览文件 @
6fa950a4
...
...
@@ -23,10 +23,7 @@ import (
// parseFormatTableSet provides a function to parse the format settings of the
// table with default value.
func
parseFormatTableSet
(
formatSet
string
)
(
*
formatTable
,
error
)
{
format
:=
formatTable
{
TableStyle
:
""
,
ShowRowStripes
:
true
,
}
format
:=
formatTable
{
ShowRowStripes
:
true
}
err
:=
json
.
Unmarshal
(
parseFormatSet
(
formatSet
),
&
format
)
return
&
format
,
err
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录