Замена нескольких наблюдений из одного столбца значениями из другого столбца в R - PullRequest
0 голосов
/ 25 мая 2019

Я пытаюсь заменить значения из двух столбцов значениями из двух других столбцов. Это довольно простой вопрос, и его задали python пользователей , однако я использую R.

У меня есть df, который выглядит следующим образом (только в гораздо большем масштабе [> 20000]):

squirrel_id    locx    locy    dist
6391           17.5    10.0    50.0
6391           17.5    10.0    20.0
6391           17.5    10.0    15.5
8443           20.5    1.0     800
6025           -5.0    -0.5    0.0

Мне нужно, для 63 белок, заменить их значения locx и locy.

Обычно я заменяю значения следующим кодом:

library(dplyr)    

df <- df %>%
   mutate(locx = ifelse (squirrel_id=="6391", "12.5", locx),
         locy = ifelse (squirrel_id=="6391", "15.5", locy),
         locx = ifelse (squirrel_id=="8443", "2.5", locx),
         locy = ifelse (squirrel_id=="8443", "80", locy)) #etc for 63 squirrels

Что дало бы мне:

squirrel_id    locx    locy    dist
6391           12.5    10.0    50.0
6391           12.5    10.0    20.0
6391           12.5    10.0    15.5
8443           2.5     80.0    800
6025           -5.0    -0.5    0.0

Но это создает дополнительные 126 строк кода, и я подозреваю, что есть более простой способ сделать это.

У меня есть все новые значения locx и locy в отдельном df, но я не знаю, как объединить эти два dataframe с помощью squirrel_id, чтобы это не испортило данные.

df со значениями, которые нужно заменить на прежние df:

squirrel_id    new_locx    new_locy   
6391           12.5        15.5 
8443           2.5         80
6025           -55.0       0.0

Как я могу сделать это более эффективно?

Ответы [ 2 ]

1 голос
/ 25 мая 2019

Вы можете left_join два кадра данных, а затем использовать оператор if_else, чтобы получить правильные locx и locy. Попробуйте:

library(dplyr)
df %>% left_join(df2, by = "squirrel_id") %>%
        mutate(locx = if_else(is.na(new_locx), locx, new_locx), # as suggested by @echasnovski, we can also use locx = coalesce(new_locx, locx)
               locy = if_else(is.na(new_locy), locy, new_locy)) %>% # or locy = coalesce(new_locy, locy)
        select(-new_locx, -new_locy)
# output
  squirrel_id  locx locy  dist
1        6391  12.5 15.5  50.0
2        6391  12.5 15.5  20.0
3        6391  12.5 15.5  15.5
4        8443   2.5 80.0 800.0
5        6025 -55.0  0.0   0.0
6        5000  18.5 18.5  10.0 # squirrel_id 5000 was created for an example of id 
# present if df but not in df2

Данные

df <- structure(list(squirrel_id = c(6391L, 6391L, 6391L, 8443L, 6025L, 
5000L), locx = c(17.5, 17.5, 17.5, 20.5, -5, 18.5), locy = c(10, 
10, 10, 1, -0.5, 12.5), dist = c(50, 20, 15.5, 800, 0, 10)), class = "data.frame", row.names = c(NA, 
-6L))
df2 <- structure(list(squirrel_id = c(6391L, 8443L, 6025L), new_locx = c(12.5, 
2.5, -55), new_locy = c(15.5, 80, 0)), class = "data.frame", row.names = c(NA, 
-3L))
0 голосов
/ 25 мая 2019

Используя данные @ ANG, вот решение data.table.Он присоединяется и обновляет оригинал df по ссылке.

library(data.table)

setDT(df)
setDT(df2)

df[df2, on = c('squirrel_id'), `:=` (locx = new_locx, locy = new_locy) ]

df

   squirrel_id  locx locy  dist
1:        6391  12.5 15.5  50.0
2:        6391  12.5 15.5  20.0
3:        6391  12.5 15.5  15.5
4:        8443   2.5 80.0 800.0
5:        6025 -55.0  0.0   0.0
6:        5000  18.5 12.5  10.0

См. Также:

как использовать merge () для обновления таблицы в R

Заменить подмножествофрейм данных с операциями соединения dplyr

R: обновление фрейма данных другим фреймом данных

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...