Сопоставление двух R фреймов данных по близости

Это на самом деле вытекает из других ответов на вопрос.

Вот мой прием:

import sys

# for current func name, specify 0 or no argument.
# for name of caller of current func, specify 1.
# for name of caller of caller of current func, specify 2. etc.
currentFuncName = lambda n=0: sys._getframe(n + 1).f_code.co_name


def testFunction():
    print "You are in function:", currentFuncName()
    print "This function's caller was:", currentFuncName(1)    


def invokeTest():
    testFunction()


invokeTest()

# end of file

Вероятное преимущество этой версии с использованием функции inspect.stack () что он должен быть в тысячи раз быстрее (см. сообщение Алекса Мелихоффа и тайминги относительно использования sys._getframe () по сравнению с использованием inspect.stack ()]. ​​

3
задан bshelt141 16 January 2019 в 16:26
поделиться

1 ответ

Данные

Прежде всего, я добавил stringsAsFactors = FALSE к вашим входным фреймам данных, потому что в моем решении проще работать со строками, чем с факторами.

df1 <- data.frame(group = rep("A", 5),
              name = c("Brandon",
                       "Kyler",
                       "Trent",
                       "Lesa",
                       "Michael"),
              gender = c("M", "F", "M", "F", "M"),
              days = c(50, 45, 32, 60, 48),
              stringsAsFactors = FALSE)

df2 <- data.frame(group = rep("B", 10),
                  name = c("Erica", 
                           "Jared",
                           "Sara",
                           "Helen",
                           "Tom",
                           "Ron",
                           "Cy",
                           "Lynn",
                           "Ken",
                           "Judy"),
                  gender = c("F", "M", "F", "F", "M", "M", "M", "F", "M", "F"),
                  days = c(47, 49, 62, 80, 74, 30, 55, 58, 63, 25),
                  stringsAsFactors = FALSE)

Решение

library(tidyverse)

# empty dataframe for the output
df2_new <- data.frame(group = character(),
                      name = character(),
                      gender = character(),
                      days = numeric(),
                      stringsAsFactors = FALSE)

for(i in 1:nrow(df1)){

  # add the row of interest to the output dataframe
  df2_new[i,] <- df2 %>% 
    mutate(day_diff = abs(days - df1$days[i])) %>%
    filter(gender == df1$gender[i]) %>% 
    slice(which.min(day_diff)) %>%
    select(-day_diff)

  # remove the newly added row from the original dataset
  df2 <- df2 %>%
    filter(!(name %in% df2_new$name))

}

Это первое решение, которое пришло в голову. В этом случае строки удаляются из df2 по мере продолжения цикла for, поскольку вы сказали, что

хотите отфильтровать df2, чтобы включить только самое близкое соответствие каждой строке в [ 116]

Вывод

df2_new

  group  name gender days
1     B Jared      M   49
2     B Erica      F   47
3     B   Ron      M   30
4     B  Sara      F   62
5     B    Cy      M   55

В моем случае код выбирал Сару вместо Линн, но это выбор 50/50.

0
ответ дан Ric S 16 January 2019 в 16:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: