Смешанное слияние в R – решение для индексов?

StackOverflow https://stackoverflow.com/questions/1301759

  •  18-09-2019
  •  | 
  •  

Вопрос

Примечание: Я изменил пример с того момента, когда впервые опубликовал.Мой первый пример был слишком упрощен, чтобы отразить реальную проблему.

У меня есть два фрейма данных, которые в одном столбце отсортированы по-разному.Я хочу сопоставить один столбец, а затем объединить значение из второго столбца.Второй столбец должен оставаться в том же порядке.

Итак, у меня есть это:

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

Проверено и работает.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top