Присоединяйтесь к файлам Excel на основе неравной временной переменной - PullRequest
0 голосов
/ 23 мая 2018

Мне нужно объединить 2 файла Excel

1-й в этом столбце:

01/01/2016 00:00
01/01/2016 00:10
01/01/2016 00:20
01/01/2016 00:30
01/01/2016 00:40
01/01/2016 00:50
01/01/2016 01:00
01/01/2016 01:10
01/01/2016 01:20
01/01/2016 01:30
01/01/2016 01:40
01/01/2016 01:50
01/01/2016 02:00
01/01/2016 02:10
01/01/2016 02:20
01/01/2016 02:30
01/01/2016 02:40
01/01/2016 02:50
01/01/2016 03:00
01/01/2016 03:10
01/01/2016 03:20
01/01/2016 03:30
01/01/2016 03:40
01/01/2016 03:50
01/01/2016 04:00
01/01/2016 04:10
01/01/2016 04:20
01/01/2016 04:30
01/01/2016 04:40
01/01/2016 04:50
01/01/2016 05:00
01/01/2016 05:10
01/01/2016 05:20
01/01/2016 05:30
01/01/2016 05:40
01/01/2016 05:50
01/01/2016 06:00
01/01/2016 06:10
01/01/2016 06:20
01/01/2016 06:30
01/01/2016 06:40
01/01/2016 06:50
01/01/2016 07:00
01/01/2016 07:10
01/01/2016 07:20
01/01/2016 07:30
01/01/2016 07:40
01/01/2016 07:50
01/01/2016 08:00
01/01/2016 08:10
01/01/2016 08:20
01/01/2016 08:30
01/01/2016 08:40
01/01/2016 08:50
01/01/2016 09:00
01/01/2016 09:10
01/01/2016 09:20
01/01/2016 09:30
01/01/2016 09:40
01/01/2016 09:50
01/01/2016 10:00
01/01/2016 10:10
01/01/2016 10:20
01/01/2016 10:30
01/01/2016 10:40
01/01/2016 10:50
01/01/2016 11:00
01/01/2016 11:10
01/01/2016 11:20
01/01/2016 11:30
01/01/2016 11:40
01/01/2016 11:50
01/01/2016 12:00
01/01/2016 12:10
01/01/2016 12:20
01/01/2016 12:30
01/01/2016 12:40
01/01/2016 12:50
01/01/2016 13:00
01/01/2016 13:10
01/01/2016 13:20
01/01/2016 13:30
01/01/2016 13:40
01/01/2016 13:50
01/01/2016 14:00
01/01/2016 14:10
01/01/2016 14:20
01/01/2016 14:30
01/01/2016 14:40
01/01/2016 14:50
01/01/2016 15:00
01/01/2016 15:10
01/01/2016 15:20
01/01/2016 15:30
01/01/2016 15:40
01/01/2016 15:50
01/01/2016 16:00
01/01/2016 16:10
01/01/2016 16:20
01/01/2016 16:30
01/01/2016 16:40
01/01/2016 16:50
01/01/2016 17:00
01/01/2016 17:10
01/01/2016 17:20
01/01/2016 17:30
01/01/2016 17:40
01/01/2016 17:50
01/01/2016 18:00
01/01/2016 18:10
01/01/2016 18:20
01/01/2016 18:30
01/01/2016 18:40
01/01/2016 18:50
01/01/2016 19:00
01/01/2016 19:10
01/01/2016 19:20
01/01/2016 19:30
01/01/2016 19:40
01/01/2016 19:50
01/01/2016 20:00
01/01/2016 20:10
01/01/2016 20:20
01/01/2016 20:30
01/01/2016 20:40
01/01/2016 20:50
01/01/2016 21:00
01/01/2016 21:10
01/01/2016 21:20
01/01/2016 21:30
01/01/2016 21:40
01/01/2016 21:50
01/01/2016 22:00
01/01/2016 22:10
01/01/2016 22:20
01/01/2016 22:30
01/01/2016 22:40
01/01/2016 22:50
01/01/2016 23:00
01/01/2016 23:10
01/01/2016 23:20
01/01/2016 23:30
01/01/2016 23:40
01/01/2016 23:50

, а во втором:

01/01/2016 05:07
01/01/2016 07:10
01/01/2016 08:19
01/01/2016 08:27
01/01/2016 09:18
01/01/2016 10:13
01/01/2016 10:23
01/01/2016 10:30
01/01/2016 10:57
01/01/2016 12:20
01/01/2016 14:50
01/01/2016 14:54
01/01/2016 15:00
01/01/2016 15:20
01/01/2016 16:12
01/01/2016 18:26
01/01/2016 19:08
01/01/2016 20:00
01/01/2016 21:15
01/01/2016 21:20
01/01/2016 22:10
01/01/2016 22:13
01/01/2016 22:18

и мне нужносделать объединение между ними, основываясь на ближайшем значении от первого файла Excel до второго.

Я пробовал vlookup и power query, но они предполагают равенство между значениями столбца.

Я действительнонужна ваша помощь.

Большое вам спасибо.

Ответы [ 3 ]

0 голосов
/ 23 мая 2018

Раствор R.Все операторы mergedplyr::*_join) работают на равенстве, поэтому ваша первая проблема - преобразование вашего первого вектора в ближайший во втором.Функция findInterval аналогична функции VLOOKUP в Excel:

findInterval(v1df$v1, v2df$v2)
#  [1] 0 1 1 1 1 1 2 2 2 2

. Здесь отображаются два артефакта:

  1. Первое значение имеет индекс 0,указывая на то, что оно находится перед первым значением в v2 (ваш второй вектор).
  2. Это не обеспечивает ближайший , оно является самым высоким без перехода.

Мы можем сдвинуть v2 для размещения.

d <- diff(v2df$v2)
units(d) <- "secs"
v2df$v2shift <- v2df$v2 - c(d[1], d)/2
v2df
#                    v2             v2shift
# 1 2016-01-01 05:07:00 2016-01-01 04:05:30
# 2 2016-01-01 07:10:00 2016-01-01 06:08:30
# 3 2016-01-01 08:19:00 2016-01-01 07:44:30

Теперь интервал работает:

findInterval(v1df$v1, v2df$v2shift)
#  [1] 1 1 1 2 2 2 2 2 3 3

Теперь мы добавим это к первым данным:

v1df$closest <- v2df$v2[findInterval(v1df$v1, v2df$v2shift)]
v1df
#                     v1             closest
# 1  2016-01-01 05:00:00 2016-01-01 05:07:00
# 2  2016-01-01 05:10:00 2016-01-01 05:07:00
# 3  2016-01-01 05:20:00 2016-01-01 05:07:00
# 4  2016-01-01 06:40:00 2016-01-01 07:10:00
# 5  2016-01-01 06:50:00 2016-01-01 07:10:00
# 6  2016-01-01 07:00:00 2016-01-01 07:10:00
# 7  2016-01-01 07:10:00 2016-01-01 07:10:00
# 8  2016-01-01 07:20:00 2016-01-01 07:10:00
# 9  2016-01-01 08:00:00 2016-01-01 08:19:00
# 10 2016-01-01 08:10:00 2016-01-01 08:19:00

и объединим:

merge(v2df["v2"], v1df, by.x="v2", by.y="closest")
#                     v2                  v1
# 1  2016-01-01 05:07:00 2016-01-01 05:00:00
# 2  2016-01-01 05:07:00 2016-01-01 05:10:00
# 3  2016-01-01 05:07:00 2016-01-01 05:20:00
# 4  2016-01-01 07:10:00 2016-01-01 06:40:00
# 5  2016-01-01 07:10:00 2016-01-01 06:50:00
# 6  2016-01-01 07:10:00 2016-01-01 07:00:00
# 7  2016-01-01 07:10:00 2016-01-01 07:10:00
# 8  2016-01-01 07:10:00 2016-01-01 07:20:00
# 9  2016-01-01 08:19:00 2016-01-01 08:00:00
# 10 2016-01-01 08:19:00 2016-01-01 08:10:00

Аналогично

dplyr::full_join(v2df["v2"], v1df, by=c("v2"="closest"))

Данные:

v1 <- as.POSIXct(c(
  '01/01/2016 05:00',
  '01/01/2016 05:10',
  '01/01/2016 05:20',
  '01/01/2016 06:40',
  '01/01/2016 06:50',
  '01/01/2016 07:00',
  '01/01/2016 07:10',
  '01/01/2016 07:20',
  '01/01/2016 08:00',
  '01/01/2016 08:10'), format='%m/%d/%Y %H:%M')

v2 <- as.POSIXct(c(
  '01/01/2016 05:07',
  '01/01/2016 07:10',
  '01/01/2016 08:19'), format='%m/%d/%Y %H:%M')

v1df <- data.frame(v1 = v1)
v2df <- data.frame(v2 = v2)
0 голосов
/ 23 мая 2018

Предполагая, что строка типа 01/01/2016 08:00 является действительной датой в вашей системе, вы можете использовать решение VBA в ADODB:

'needs reference to MS ActiveX Data Object Library x.x reference
'menu: Tools->References... in VBA Code Pane

Sub GetDataByNearestDates()
    Dim sSQL As String, sConn As String
    Dim oConn As ADODB.Connection
    Dim oRst As ADODB.Recordset

    On Error GoTo Err_GetDataByNearestDates

    sSQL = "SELECT t1.A, t2.B, t1.A - t2.B" & vbCr
    sSQL = sSQL & "FROM (" & vbCr
    sSQL = sSQL & "SELECT [F1] AS A FROM [Sheet1$]" & vbCr
    sSQL = sSQL & ") AS t1" & vbCr
    sSQL = sSQL & ", (" & vbCr
    sSQL = sSQL & "SELECT [F1] AS B FROM [Sheet2$]" & vbCr
    sSQL = sSQL & ") AS t2" & vbCr
    sSQL = sSQL & "WHERE ((t1.A-t2.B >-0.004) AND (t1.A-t2.B <=0.004));" & vbCr

    'if you use column-headers, change HDR=NO to HDR=YES
    sConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties='Excel 12.0 Macro;HDR=NO';"

    Set oConn = New ADODB.Connection
    With oConn
        .ConnectionString = sConn
        .Open
        Set oRst = oConn.Execute(sSQL)
    End With

    ThisWorkbook.Worksheets(3).Cells.Clear
    ThisWorkbook.Worksheets(3).Range("A1").CopyFromRecordset oRst

Exit_GetDataByNearestDates:
    On Error Resume Next
    If Not oRst Is Nothing Then oRst.Close: Set oRst = Nothing
    If Not oConn Is Nothing Then oConn.Close: Set oConn = Nothing
    Exit Sub

Err_GetDataByNearestDates:
    MsgBox Err.Description, vbExclamation, Err.Number
    Resume Exit_GetDataByNearestDates

End Sub

Приведенный выше код создает результирующий набор «ближайших значений» в Sheet3

Чтобы использовать вышеуказанный код, вам необходимо:

  1. создать пустой файл Excel (с 3 рабочими листами)
  2. скопировать данные из рабочей книги1 в Sheet1
  3. скопировать данные из рабочей книги2 в Sheet2
  4. перейти на панель кода VBA (ALT + F11)
  5. вставить новый модуль (меню Insert->Module)
  6. вставьте в него вышеуказанный код
  7. и ... сохраните файл как * .xlsm файл

Чтобы запустить код, переместите курсор в тело процедуры GetDataByNearestDates инажмите F5.Набор результатов должен выглядеть так:

2016-01-01 05:10    2016-01-01 05:07
2016-01-01 07:10    2016-01-01 07:10
2016-01-01 08:20    2016-01-01 08:19
2016-01-01 08:30    2016-01-01 08:27
2016-01-01 09:20    2016-01-01 09:18
2016-01-01 10:10    2016-01-01 10:13
2016-01-01 10:20    2016-01-01 10:23
2016-01-01 10:30    2016-01-01 10:30
2016-01-01 11:00    2016-01-01 10:57
2016-01-01 12:20    2016-01-01 12:20
2016-01-01 14:50    2016-01-01 14:50
2016-01-01 14:50    2016-01-01 14:54
2016-01-01 15:00    2016-01-01 15:00
2016-01-01 15:20    2016-01-01 15:20
2016-01-01 16:10    2016-01-01 16:12
2016-01-01 18:30    2016-01-01 18:26
2016-01-01 19:10    2016-01-01 19:08
2016-01-01 20:00    2016-01-01 20:00
2016-01-01 21:10    2016-01-01 21:15
2016-01-01 21:20    2016-01-01 21:15
2016-01-01 21:20    2016-01-01 21:20
2016-01-01 22:10    2016-01-01 22:10
2016-01-01 22:10    2016-01-01 22:13
2016-01-01 22:20    2016-01-01 22:18
0 голосов
/ 23 мая 2018

Если ваш более длинный список находится в столбце A, а ваш более короткий список - в столбце B (при условии отсутствия заголовков и т. Д.), То следующая формула будет VLOOKUP ближайшего нижнего значения:

=VLOOKUP(B1,A:A,1,1)
...