Смешанное слияние в R – решение для индексов?
Вопрос
Примечание: Я изменил пример с того момента, когда впервые опубликовал.Мой первый пример был слишком упрощен, чтобы отразить реальную проблему.
У меня есть два фрейма данных, которые в одном столбце отсортированы по-разному.Я хочу сопоставить один столбец, а затем объединить значение из второго столбца.Второй столбец должен оставаться в том же порядке.
Итак, у меня есть это:
state<-c("IA","IA","IA","IL","IL","IL")
value1<-c(1,2,3,4,5,6)
s1<-data.frame(state,value1)
state<-c("IL","IL","IL","IA","IA","IA")
value2<-c(3,4,5,6,7,8)
s2<-data.frame(state,value2)
s1
s2
который возвращает это:
> s1
state value1
1 IA 1
2 IA 2
3 IA 3
4 IL 4
5 IL 5
6 IL 6
> s2
state value2
1 IL 3
2 IL 4
3 IL 5
4 IA 6
5 IA 7
6 IA 8
и я хочу этого:
state value1 value2
1 IA 1 6
2 IA 2 7
3 IA 3 8
4 IL 4 3
5 IL 5 4
6 IL 6 5
Я собираюсь свести себя с ума, пытаясь решить эту проблему.Похоже, это должна быть простая проблема с индексами.
Решение
Есть несколько способов сделать это (в конце концов, это R), но я думаю, что наиболее очевидным является создание индекса.Нам нужна функция, которая создает последовательный индекс (начиная с единицы и заканчивая количеством наблюдений).
seq_len(3)
> [1] 1 2 3
Но нам нужно вычислить этот индекс внутри каждой группирующей переменной (состояния).Для этого мы можем использовать R ave
функция.В качестве первого аргумента он принимает число, затем факторы группировки и, наконец, функцию, которая будет применяться в каждой группе.
s1$index <- with(s1,ave(value1,state,FUN=seq_len))
s2$index <- with(s2,ave(value2,state,FUN=seq_len))
(Обратите внимание на использование with
, который сообщает R искать переменные в среде/фрейме данных.Это лучше, чем использование s1$value1, s2$value2 и т. д.)
Теперь мы можем просто объединить (объединить) два фрейма данных (по переменным, присутствующим в обоих фреймах данных:состояние и индекс).
merge(s1,s2)
который дает
state index value1 value2
1 IA 1 1 6
2 IA 2 2 7
3 IA 3 3 8
4 IL 1 4 3
5 IL 2 5 4
6 IL 3 6 5
Чтобы это работало, в каждом кадре данных должно быть одинаковое количество наблюдений по состояниям.
[Редактировать:прокомментировал код для ясности.] [Редактировать:Использовал seq_len вместо создания новой функции, как предложил Хэдли.]
Другие советы
ПРИМЕЧАНИЕ:Проверьте пятый комментарий к ответу выше.Решение должно быть
s1$index <- with(s1,ave(value1,state,FUN=seq_along))
s2$index <- with(s2,ave(value2,state,FUN=seq_along))
Проверено и работает.