Assigning entire column of data to specific column of an array in VBA
First things first, your variables. The names aren't great. For the ws1 to ws3 you're using numbers, which should tell you it's not specific enough or you aren't being effective with your variables.

Worksheets have a CodeName property - View Properties window (F4) and the (Name) field can be used as the worksheet name. This way you can avoid Sheets("Data") and instead just use Data.

Also lastcol3 - what's that? lastColumn? Why the 3, also you missed camelCase on that one. Standard VBA naming conventions have camelCase for local variables and PascalCase for other variables and names. You could just call it resultsLastColumn instead.

i,r,j,k - these are counters right?

r - currentColumn. i,j,k are acceptable, but personal preference I like to avoid those.

Dim arr - When you don't define your variable, VBA will declare it as a Variant, which are objects:

Performance. A variable you declare with the Object type is flexible enough to contain a reference to any object. However, when you invoke a method or property on such a variable, you always incur late binding (at run time). To force early binding (at compile time) and better performance, declare the variable with a specific class name, or cast it to the specific data type.

By not declaring variables, you could possibly be paying a penalty.

In this case, it is a variant, but it's good to note for the future. It should have a more descriptive name, though.

lastColumn and numRows are integers - Integers - integers are obsolete. According to msdn VBA silently converts all integers to long.

Additionally, your numRows is set to 1000 and never changed. Why not

Const NUMBER_OF_ROWS As Long = 1000


Your indenting is non-existent. 
It's good practice to indent all of your code that way Labels will stick out as obvious.

Always turn on Option Explicit. You can have it automatically by going to Tools -> Options in the VBE and checking the Require Variable Declaration option. This way if you have any variables not defined, the compiler will let you know. In this case your variable wb isn't defined.



You use Application.Calculation a lot. You set it to Manual and do some stuff, then set it to Automatic. Then you loop up to 5000 times in your r loop turning it manual and back to automatic. None of that is needed. The calculations you're doing in VBA aren't affected by the worksheet calculation. I don't know what kind of resources that's using, but I can't imagine it's helping.



Comments - "code tell you how, comments tell you why". The code should speak for itself, if it needs a comment, it might need to be made more clear. If not, the comment should describe why you're doing something rather than how you're doing it. Here are a few reasons to avoid comments all together.



ActiveSheet.DisplayPageBreaks = False - this will only work on the active sheet, what if the sheet isn't active. Why not tell it which sheet to do it on?

Also your last Application.EnableEvents is missing the ..



I don't quite understand this line

ws1.Range("D1") = classArray(1, r)


Does this need to move down column D with the class names?



With your arr array

ReDim arr(1 To NUMBER_OF_ROWS, 1 To resultsLastColumn)
For r = 1 To resultsLastColumn
    ws1.Range("D1") = classArray(1, r)
    For i = 1 To NUMBER_OF_ROWS
        arr(i, r) = ws1.Cells(6 + i, 11)
    Next
Next
For k = 1 To resultsLastColumn
    For j = 1 To NUMBER_OF_ROWS
        If arr(j, k) = 15 Then
            ThisWorkbook.Data.Cells(6 + j, 4) = 1 + ThisWorkbook.Data.Cells(6 + j, 4)
        ElseIf arr(j, k) = 28 Then
            ThisWorkbook.Data.Cells(6 + j, 5) = 1 + ThisWorkbook.Data.Cells(6 + j, 5)
        ElseIf arr(j, k) = 50 Then
            ThisWorkbook.Data.Cells(6 + j, 6) = 1 + ThisWorkbook.Data.Cells(6 + j, 6)
        End If
    Next
Next


This is pretty inefficient. Why not just pull everything into the array and do the sorting in it, rather than on the sheet. That will be quicker.

arr = Data.Range(Cells(1, 6), Cells(NUMBER_OF_ROWS, resultsLastColumn))


Now you can loop with your j and k in the arr or just eliminate k and reuse i.



So at the very least, you'll have this

Option Explicit
Private Sub UpdateData()

    Application.ScreenUpdating = False
    Application.DisplayStatusBar = False
    Application.EnableEvents = False
    ActiveSheet.DisplayPageBreaks = False
    Application.Calculation = xlCalculationManual

    Const NUMBER_OF_ROWS As Long = 1000
    Dim resultsLastColumn As Integer
    Dim classArray As Variant
    Dim i As Long
    Dim j As Long
    Dim k As Long
    Dim arr As Variant

    resultsLastColumn = Results.Cells(4, Results.Columns.Count).End(xlToLeft).Column - 1
    ReDim arr(1 To NUMBER_OF_ROWS, 1 To resultsLastColumn)
    classArray = Results.Range(Results.Cells(4, 2), Results.Cells(4, resultsLastColumn + 1))

    ClassCalculationSheet.Range("D1:D" &amp; resultsLastColumn) = classArray()

    arr = Data.Range(Cells(1, 6), Cells(NUMBER_OF_ROWS, resultsLastColumn))
    For j = 1 To resultsLastColumn
        For i = 1 To NUMBER_OF_ROWS
            If arr(i, j) = 15 Then
                Data.Cells(6 + j, 4) = 1 + Data.Cells(6 + i, 4)
            ElseIf arr(i, j) = 28 Then
                Data.Cells(6 + j, 5) = 1 + Data.Cells(6 + i, 5)
            ElseIf arr(i, j) = 50 Then
                Data.Cells(6 + j, 6) = 1 + Data.Cells(6 + i, 6)
            End If
        Next
    Next

    Application.Calculation = xlCalculationAutomatic
    Application.ScreenUpdating = True
    Application.DisplayStatusBar = True
    Application.EnableEvents = True
    ActiveSheet.DisplayPageBreaks = True

End Sub


Some tweaking might be needed as I can't run the macro to see what needs adjusting.