Объединение двух фреймов данных с неуникальным столбцом - PullRequest
0 голосов
/ 28 мая 2018

Synopsys

У меня уже есть решение, использующее цикл "for", но мне было интересно, есть ли элегантные способы, возможно, с использованием dplyr или базы R.

Существующие данные

2 кадра данных.Оба имеют точное количество неуникальных маркеров в точном порядке;кроме ЭЭГ имеет непредсказуемое количество нулей.Набор данных о поведении «поведение» имеет число стимулов «стим», связанных с маркером.(на самом деле у меня есть больше столбцов в каждом фрейме данных, но я не включил их для простоты),Сохранение порядка строк является обязательным.

Результат должен выглядеть следующим образом:

eeg2 = data.frame(
  marker = c(0,0,1,0,0,2,0,0,3,0,0,1,0,0,2,0,0,3,0,7,0,13),
  stim   = c(0,0,168,0,0,168,0,0,168,0,0,78,0,0,78,0,0,78,0,23,0,55)
)

Мое решение

Это делает работу и производительность неплохой для большого набора данных eeg.

eeg2=eeg;
eeg2$stim=NA;

lrow=1;
for(i in 1:nrow(behav)){
  behav_marker = behav[i, "marker"];

  for(j in lrow:nrow(eeg)){
    eeg_marker = eeg[j, "marker"];
    if(eeg_marker == behav_marker){
      eeg2[j,'stim'] = behav[i,'stim'];
      lrow = j+1;
      break;
    }
  }
}

Вопрос Можно ли улучшить мое решение более элегантным способом, используя dplyr илибазовые функции R?

Ответы [ 2 ]

0 голосов
/ 28 мая 2018

A base решение уже было предоставлено для полноты, вот как я бы подошел, используя dplyr:

Использование dplyr::left_join() для объединения eeg и behav, а затем заполнениеNA s с 0 с dplyr::mutate():

eeg2 <- dplyr::left_join(eeg, behav, by = c("marker"))

eeg2 <- dplyr::mutate(eeg2, stim = dplyr::if_else(is.na(stim), 0, stim))

Результат:

   marker stim
1       0    0
2       0    0
3       1  168
4       1   78
5       0    0
6       0    0
7       2  168
8       2   78
9       0    0
10      0    0
11      3  168
12      3   78
13      0    0
14      0    0
15      1  168
16      1   78
17      0    0
18      0    0
19      2  168
20      2   78
21      0    0
22      0    0
23      3  168
24      3   78
25      0    0
26      7   23
27      0    0
28     13   55

В этом конкретном случае я бы порекомендовал использовать трубы (%>%) с magrittr (добавляет немного накладных расходов, но делает код немного короче и лучше течет:

eeg2 <- dplyr::left_join(eeg, behav, by = c("marker")) %>% 
  dplyr::mutate(stim = dplyr::if_else(is.na(stim), 0, stim))
0 голосов
/ 28 мая 2018

Если проблема возникает только в строках с нулями, но все остальное одинаково в том же порядке, вы можете решить эту проблему, определив столбец stim как только нули, а затем заполнив строки ненулевымзначение для marker с соответствующим значением behav:

eeg$stim <- 0
eeg$stim[eeg$marker!=0] <- behav$stim

eeg
   # marker stim
# 1       0    0
# 2       0    0
# 3       1  168
# 4       0    0
# 5       0    0
# 6       2  168
# 7       0    0
# 8       0    0
# 9       3  168
# 10      0    0
# 11      0    0
# 12      1   78
# 13      0    0
# 14      0    0
# 15      2   78
# 16      0    0
# 17      0    0
# 18      3   78
# 19      0    0
# 20      7   23
# 21      0    0
# 22     13   55
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...