Terms of a Sum in a R Expression

Terms of a sum in a R expression

You can use a recursive function to crawl the parse tree:

foo <- function(x) {
if (is.call(x)) y <- as.list(x) else return(x)

#stop crawling if not a call to `+`
if (y[[1]] != quote(`+`)) return(x)

y <- lapply(y, foo)

return(y[-1]) #omit `+` symbol
}

expr1 <- expression(a + b * c + d + e * f)
unlist(foo(expr1[[1]]))
#[[1]]
#a
#
#[[2]]
#b * c
#
#[[3]]
#d
#
#[[4]]
#e * f

expr2 <- expression(a + b * c + d + e * (f + g))
unlist(foo(expr2[[1]]))
#[[1]]
#a
#
#[[2]]
#b * c
#
#[[3]]
#d
#
#[[4]]
#e * (f + g)

How to sum the values in Listint[] using Java 8

You want to flatMap to an IntStream. After that, taking the sum is easy.

int sum = counts.stream()
.flatMapToInt(IntStream::of)
.sum();

How to count TRUE values in a logical vector

The safest way is to use sum with na.rm = TRUE:

sum(z, na.rm = TRUE) # best way to count TRUE values

which gives 1.

There are some problems with other solutions when logical vector contains NA values.

See for example:

z <- c(TRUE, FALSE, NA)

sum(z) # gives you NA
table(z)["TRUE"] # gives you 1
length(z[z == TRUE]) # f3lix answer, gives you 2 (because NA indexing returns values)

Additionally table solution is less efficient (look at the code of table function).

Also, you should be careful with the "table" solution, in case there are no TRUE values in the logical vector. See for example:

z <- c(FALSE, FALSE)
table(z)["TRUE"] # gives you `NA`

or

z <- c(NA, FALSE)
table(z)["TRUE"] # gives you `NA`

What does axis = 0 do in Numpy's sum function?

All that is going on is that numpy is summing across the first (0th) and only axis. Consider the following:

In [2]: a = np.array([1, 2, 3])

In [3]: a.shape
Out[3]: (3,)

In [4]: len(a.shape) # number of dimensions
Out[4]: 1

In [5]: a1 = a.reshape(3,1)

In [6]: a2 = a.reshape(1,3)

In [7]: a1
Out[7]:
array([[1],
[2],
[3]])

In [8]: a2
Out[8]: array([[1, 2, 3]])

In [9]: a1.sum(axis=1)
Out[9]: array([1, 2, 3])

In [10]: a1.sum(axis=0)
Out[10]: array([6])

In [11]: a2.sum(axis=1)
Out[11]: array([6])

In [12]: a2.sum(axis=0)
Out[12]: array([1, 2, 3])

So, to be more explicit:

In [15]: a1.shape
Out[15]: (3, 1)

a1 is 2-dimensional, the "long" axis being the first.

In [16]: a1[:,0] # give me everything in the first axis, and the first part of the second
Out[16]: array([1, 2, 3])

Now, sum along the first axis:

In [17]: a1.sum(axis=0)
Out[17]: array([6])

Now, consider a less trivial two-dimensional case:

In [20]: b = np.array([[1,2,3],[4,5,6]])

In [21]: b
Out[21]:
array([[1, 2, 3],
[4, 5, 6]])

In [22]: b.shape
Out[22]: (2, 3)

The first axis is the "rows". Sum along the rows:

In [23]: b.sum(axis=0)
Out[23]: array([5, 7, 9])

The second axis are the "columns". Sum along the columns:

In [24]: b.sum(axis=1)
Out[24]: array([ 6, 15])

In Excel VBA, how to convert SUM function to its explicit form?

This feels like a post on Code Golf. Here's my version of a function that can do this.

Function ExplicitSum(ByVal expression As String) As String
Dim strStart As Long, strEnd As Long
strStart = InStr(1, UCase(expression), "SUM(") + 4
If strStart = 0 Then
'SUM not found
ExplicitSum = expression
Exit Function
End If
strEnd = InStr(strStart + 1, expression, ")")
If strEnd = 0 Then
'closing bracket not found
ExplicitSum = expression
Exit Function
End If

Dim LeftText As String, RightText As String, AddressText As String
LeftText = Replace(Left(expression, strStart - 1), "sum(", "(", Compare:=vbTextCompare)
AddressText = Mid(expression, strStart, strEnd - strStart)
RightText = Right(expression, Len(expression) - strEnd + 1)

If InStr(1, UCase(RightText), "SUM(") <> 0 Then
'Recursion will handle multiple sums in the same formula
RightText = ExplicitSum(RightText)
End If

Dim SumRange As Range
On Error Resume Next
Set SumRange = Range(AddressText)
On Error GoTo 0
If SumRange Is Nothing Then
'Invalid AddressText - Named Ranges or Indirect reference
ExplicitSum = LeftText & AddressText & RightText
Exit Function
End If

Dim Addresses() As String
ReDim Addresses(1 To SumRange.Cells.Count)

Dim cell As Range, i As Long: i = 1
For Each cell In SumRange
Addresses(i) = cell.Address(False, False)
i = i + 1
Next cell

ExplicitSum = LeftText & Join(Addresses, "+") & RightText
End Function

Examples of how to use the function:

Sub test()
MsgBox ExplicitSum("=5+sum(A1:D1)/20")
'Displays "=5+(A1+B1+C1+D1)/20"
End Sub

Sub ExampleUsage()
'Put the formula back into the cell after transforming
Range("E1").Formula = ExplicitSum(Range("E1").Formula)
End Sub

Private Sub Worksheet_Change(ByVal Target As Range)
'Run on every cell with SUM in its formula
If LCase(Target.Cells(1,1).Formula) Like "*sum(*" Then Target.Cells(1,1).Formula = ExplicitSum(Target.Cells(1,1).Formula)
End Sub
  1. Will work with complex formulas.

  2. Will work with multiple SUMS in the same formula.

  3. Will work with Named Ranges inside the Sum.

Python - sum values in dictionary

sum(item['gold'] for item in myList)


Related Topics



Leave a reply



Submit