对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