R: Создать новый столбец в кадре данных, используя имя столбца, условие и значение из другого кадра данных. - PullRequest
0 голосов
/ 28 марта 2019

Рассмотрим базовый кадр данных как:

data <-  data.frame(amount_bin = c("10K-25K", "25K-35K", "35K-45K", "45K-50K", "50K+", "10K-25K", "25K-35K", "35K-45K", "45K-50K", "50K+", "10K-25K", "25K-35K", "35K-45K", "45K-50K", "50K+"),
                   risk_score = c("0-700", "700-750", "750-800", "800-850", "850-900", "0-700", "700-750", "750-800", "800-850", "850-900", "0-700", "700-750", "750-800", "800-850", "850-900"))

и группирование информации в другом фрейме данных как:

group_info <- data.frame(variable = c("amount_bin_group", "amount_bin_group", "amount_bin_group", "amount_bin_group", "amount_bin_group",
                                 "risk_score_group", "risk_score_group", "risk_score_group", "risk_score_group", "risk_score_group"),
                    bin = c("10K-25K", "25K-35K", "35K-45K", "45K-50K", "50K+",
                            "0-700", "700-750", "750-800", "800-850", "850-900"),
                    group = c("1", "1", "2", "2", "3",
                              "a", "a", "a", "b", "b"))

Я хочу создать 2 столбца в базовом фрейме данных (data) с именами "amount_bin_group" и "risk_score_group", который принимает значения из столбца group_info $ group, когда столбцы bin из group_info и data совпадают. Для простоты давайте предположим, что базовый столбец всегда будет именем переменной group_info $ минус строка «group». Это подразумевает, что, когда мы хотим создать столбец amount_bin_group, базовый столбец всегда будет amount_bin в базовом кадре данных.

Ожидаемый кадр данных результата:

final_data <-  data.frame(amount_bin = c("10K-25K", "25K-35K", "35K-45K", "45K-50K", "50K+", "10K-25K", "25K-35K", "35K-45K", "45K-50K", "50K+", "10K-25K", "25K-35K", "35K-45K", "45K-50K", "50K+"),
                   risk_score = c("0-700", "700-750", "750-800", "800-850", "850-900", "0-700", "700-750", "750-800", "800-850", "850-900", "0-700", "700-750", "750-800", "800-850", "850-900"),
                   amount_bin_group = c("1", "1", "2", "2", "3", "1", "1", "2", "2", "3", "1", "1", "2", "2", "3"),
                   risk_score_group = c("a", "a", "a", "b", "b", "a", "a", "a", "b", "b", "a", "a", "a", "b", "b"))

Решение, которое я только что подумал, заключается в итеративном объединении фреймов данных, т. Е.

final_data <- merge(data, group_info[, c("bin", "group")], by.x = "amount_bin", by.y = "bin")

final_data$amount_bin_group <- final_data$group
final_data$group <- NULL

Но я уверен, что может быть более эффективное решение. Обратите внимание, что таких столбцов несколько, а не только два. Так что, может быть, петля поможет.

Ответы [ 2 ]

1 голос
/ 28 марта 2019

Вы можете просто использовать цикл for, чтобы объединить разные наборы:

for (i in unique(group_info$variable)) {
  data <- merge(
    data, group_info[group_info$variable==i,c("bin","group")],
    by.x=sub("_group","",i), by.y="bin"
  )
  names(data)[names(data)=="group"] <- i
}
1 голос
/ 28 марта 2019

Ваша group_info просто слишком аккуратна.Я не могу поверить, что на самом деле говорю это.Разбивая это либо на два кадра данных, либо разбивая каждую половину на свой собственный столбец, вы позволяете себе сделать простое соединение слева, чтобы получить ответ.

final_data_calc <- data %>%
  left_join(
    group_info %>% 
      filter(variable == 'amount_bin_group') %>% 
      rename(amount_bin_group = group,amount_bin = bin) %>% 
      select(-variable)
  ) %>%
  left_join(
    group_info %>% 
      filter(variable == 'risk_score_group') %>% 
      rename(risk_score_group = group,risk_score = bin) %>% 
      select(-variable)
  )

#   amount_bin risk_score amount_bin_group risk_score_group
#1     10K-25K      0-700                1                a
#2     25K-35K    700-750                1                a
#3     35K-45K    750-800                2                a
#4     45K-50K    800-850                2                b
#5        50K+    850-900                3                b
#6     10K-25K      0-700                1                a
#7     25K-35K    700-750                1                a
#8     35K-45K    750-800                2                a
#9     45K-50K    800-850                2                b
#10       50K+    850-900                3                b
#11    10K-25K      0-700                1                a
#12    25K-35K    700-750                1                a
#13    35K-45K    750-800                2                a
#14    45K-50K    800-850                2                b
#15       50K+    850-900                3                b
...