对EXCEL 2010中的一列中的唯一值进行计数,或对100万行中的R进行计数
在search论坛后,我没有find这个问题的好办法。 如果我错过了,请告诉我。
我需要计算EXCEL 2010中一列中的唯一值。
工作表有100万行10列。 所有单元格值都是string或数字。
我在Excel中的列中使用了计数唯一值的解决scheme
=SUMPRODUCT((A2:A1000000<>"")/COUNTIF(A2:A100000,A2:A1000000&""))
但是,它运行了很长时间,EXCEL几乎被冻结了。 而且,它在Win 7中生成了25个进程。
有更有效的方法来做到这一点吗?
另外,在列中,所有值都具有格式
AX_Y here, A is a character, X is an integer, Y is an integer from 1 to 10. For example, A5389579_10
在(包括)不足之后,我需要切断这个部分。 例如,
A5389579
这是我需要在一列中的所有单元格中作为唯一值计算。
For example, A5389579_10 A1543848_6 A5389579_8
这里,下划线后删除部分后的唯一值有2。
如何在EXCEL VBA和R(如果没有EXCEL有效的解决scheme)呢?
如果您想通过VBA执行此操作,则可以利用Collection
对象。 由于集合只能包含唯一值,因此尝试将所有input数据添加到集合将导致一组唯一值。 下面的代码获取选定范围内的所有variables,然后将具有不同值的数组输出到另一个表(在本例中为名为Output的表)。
Sub ReturnDistinct() Dim Cell As Range Dim i As Integer Dim DistCol As New Collection Dim DistArr() Dim OutSht As Worksheet Dim LookupVal As String Set OutSht = ActiveWorkbook.Sheets("Output") '<~~ Define sheet to putput array If TypeName(Selection) <> "Range" Then Exit Sub 'Add all distinct values to collection For Each Cell In Selection If InStr(Cell.Value, "_") > 0 Then LookupVal = Mid(Cell.Value, 1, InStr(Cell.Value, "_") - 1) Else LookupVal = Cell.Value End If On Error Resume Next DistCol.Add LookupVal, CStr(LookupVal) On Error GoTo 0 Next Cell 'Write collection to array ReDim DistArr(1 To DistCol.Count, 1 To 1) For i = 1 To DistCol.Count Step 1 DistArr(i, 1) = DistCol.Item(i) Next i 'Outputs distinct values OutSht.Range("A1:A" & UBound(DistArr)).Value = DistArr End Sub
请注意,由于此代码将所有不同值写入OutSht
的单个列,因此如果数据集中存在多个1,048,576个不同的值,则会返回错误。 在这种情况下,您将不得不将数据分成多个输出列。
对于您的具体请求计数,请使用下面的公式中的=COUNTA(GetUniques(LEFT("A1:A100000",FIND("_","A1:A100000")-1))
作为数组公式+ Shift + Enter键。
它也接受多个范围/值(例如GetUniques("A1:A10","B2:E4")
)
Function GetUniques(ParamArray args()) Dim arg, ele, arr, i As Long Dim c As Collection Set c = New Collection For Each arg In args If TypeOf arg Is Range Then If arg.Count = 1 Then arr = array(arg.value) Else arr = arg.Value End If ElseIf VarType(arg) > vbArray Then arr = arg Else arr = Array(arg) End If For Each ele In arr On Error Resume Next c.Add ele, VarType(ele) & "|" & CStr(ele) On Error GoTo 0 Next ele Next arg If c.Count > 0 Then ReDim arr(0 To c.Count - 1) For i = 0 To UBound(arr) arr(i) = c(i + 1) Next i Set c = Nothing GetUniques = arr End If End Function
编辑:增加了范围的性能优化(一次加载到一个数组 – 比通过范围枚举快得多)
在R:
# sample data df <- data.frame(x=1:1000000, y=sample(1e6:(1e7-1),1e6,replace=T)) df$y <- paste0("A",df$y,"_",sample(1:10,1e6,replace=T)) # this does the work... length(unique(sub("_[0-9]+","",df$y))) # [1] 946442 # and it's fast... system.time(length(unique(sub("_[0-9]+","",df$y)))) # user system elapsed # 2.01 0.00 2.02
在Excel 2010中…在下一列中添加(如果原始数据在A:A中joinB1)= 1 / COUNTIF(A:A,A1),并将col B复制到数据的底部。 根据你的电脑它可能会长时间计算,但它会工作。 然后复制列B和粘贴值本身。
然后SUM col B