Как сделать левое соединение, в котором строка, взятая из «данных B», отличается от строки, в которой указан идентификатор?

#r

#r

Вопрос:

У меня есть фрейм данных «A» с двумя столбцами, в первом есть названия городов (уникальные значения), во втором есть NA, который я хочу заполнить безработицей.

фрейм данных «B» содержит столбец с названиями городов, но безработица не находится в той же строке, если быть точным, она всегда находится на 1 строку ниже.

Как бы вы объединили эти два данных, чтобы R просматривал первый столбец фрейма данных «A», находил его соответствие в фрейме данных «B» и заменял NA из второго столбца фрейма данных «A» значением на 1 строку ниже строки, в которой выполнено совпадение.

Вот некоторая обобщенная версия того, как будут выглядеть фреймы данных A и B.

 names= c("Bogotá", "Medellín")
data_frame_A= as.data.frame(names, ncol=1)
colnames(data_frame_A)= "city"
data_frame_A$Unemployment = NA
data_frame_A
  

фрейм данных B выглядит примерно так

 names= c("Bogotá", "life_exp","Unemployment","Medellín","life_exp","Unemployment")
data_frame_B= as.data.frame(names, ncol=1)
colnames(data_frame_B)= "city"
data_frame_B$column_20 = runif(6, 0.5, 0.8)
data_frame_B
  

Как бы вы тогда объединили эти две данные?

Комментарии:

1. У вас всегда есть две строки между каждым городом в data_frame_B ? Или доступные переменные для каждого города меняются

2. В качестве альтернативы, знаете ли вы, что все города в data_frame_B отображаются в data_frame_A? или есть какой-то другой способ узнать, какие строки в B являются новыми городами, а не просто читать их?

3. 1. Всегда одинаковое количество строк после названия города, пока не появятся данные о безработице. 2. да, отображаются все города o.

Ответ №1:

Вот метод, который проверяет, находится ли каждый city в data_frame_B data_frame_A , чтобы назначить строки каждому городу. Мы создаем новый столбец с фактическим названием города, а затем мы можем spread разложить переменные по их собственным столбцам. После этого вы можете снова присоединиться к data_frame_A , если там есть нужные вам столбцы.

 library(tidyverse)
data_frame_A <- structure(list(city = structure(1:2, .Label = c("Bogotá", "Medellín"), class = "factor"), Unemployment = c(NA, NA)), row.names = c(NA, -2L), class = "data.frame")
data_frame_B <- structure(list(city = structure(c(1L, 2L, 4L, 3L, 2L, 4L), .Label = c("Bogotá", "life_exp", "Medellín", "Unemployment"), class = "factor"), column_20 = c(0.653383622108959, 0.685130500583909, 0.616564040770754, 0.731770524056628, 0.53738643436227, 0.571727990615182)), row.names = c(NA, -6L), class = "data.frame")

data_frame_B %>%
  group_by(city_id = cumsum(city %in% data_frame_A$city)) %>%
  mutate(city_name = first(city)) %>%
  filter(city_name != city) %>%
  spread(city, column_20)
#> # A tibble: 2 x 4
#> # Groups:   city_id [2]
#>   city_id city_name life_exp Unemployment
#>     <int> <fct>        <dbl>        <dbl>
#> 1       1 Bogotá       0.685        0.617
#> 2       2 Medellín     0.537        0.572
  

Создано 2019-04-22 пакетом reprex (версия 0.2.1)

Ответ №2:

Устанавливая случайное начальное значение в примечании в конце, чтобы сделать данные воспроизводимыми, мы можем использовать следующее двойное левое соединение:

 library(sqldf)

sqldf("select a.city, b2.[column_20]
  from [data_frame_A] as a 
  left join [data_frame_B] as b using(city)
  left join [data_frame_B] as b2 on b2.rowid = b.rowid   1")
  

отдающий:

       city column_20
1   Bogotá 0.7364915
2 Medellín 0.7821402
  

Примечание

 set.seed(123)

names= c("Bogotá", "Medellín")
data_frame_A= as.data.frame(names, ncol=1)
colnames(data_frame_A)= "city"
data_frame_A$Unemployment = NA

names= c("Bogotá", "life_exp","Unemployment","Medellín","life_exp","Unemployment")
data_frame_B= as.data.frame(names, ncol=1)
colnames(data_frame_B)= "city"
data_frame_B$column_20 = runif(6, 0.5, 0.8)