#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)