Как назначить значения на основе другого фрейма данных с разным количеством элементов? - PullRequest
0 голосов
/ 28 февраля 2020

Вот воспроизводимый пример:

data <- data.frame(A1=c("ao","ao","zo","ao","zo","ao","jo","jo","ko"),B1=c("y1","y1","y2","y2","y1","y1","y2","y2","y1"))

> data
  A1 B1
1 ao y1
2 ao y1
3 zo y2
4 ao y2
5 zo y1
6 ao y1
7 jo y2
8 jo y2
9 ko y1

sor <- data.frame(A1=c("ao","ko","jo","zo","po"),y1=c(10,20,30,0,50),y2=c(22,33,44,55,66))

> sor
  A1 y1 y2
1 ao 10 22
2 ko 20 33
3 jo 30 44
4 zo  0 55
5 po 50 66

Здесь data - основной фрейм данных, а sor - стандартный фрейм данных. Я хочу создать новый столбец VAL в data и назначить значения на основе фрейма данных sor (проверка должна быть сделана в строках и столбцах), а NA не существует в sor.

Это требуемый вывод.

> data
  A1 B1 VAL
1 ao y1  10
2 ao y1  10
3 zo y2  55
4 ao y2  22
5 zo y1   0
6 ao y1  10
7 jo y2  44
8 jo y2  44
9 ko y1  20

Это возможно с помощью циклов for, и я устал, и получил результат с помощью циклов for. Но у меня есть большое количество строк в моем фрейме данных, и использование циклов for не будет эффективным.

Существует ли эффективный способ сделать это, кроме использования циклов for в R?

Ответы [ 2 ]

3 голосов
/ 28 февраля 2020

Вы можете использовать data.table пакет:

library(data.table)
setDT(data)[sor, VAL := i.y1, on = "A1"]

#    A1 B1 VAL
# 1: ao y1  10
# 2: ao y1  10
# 3: zo y2   0
# 4: ao y2  10
# 5: zo y1   0
# 6: ao y1  10
# 7: jo y2  30
# 8: jo y2  30
# 9: ko y1  20
2 голосов
/ 28 февраля 2020

В базе R мы можем создать матрицу индекса строки-столбца с match и использовать ее для подстановки значений из sor и создания нового столбца.

data$VAL <- as.numeric(sor[cbind(match(data$A1,sor$A1),match(data$B1, names(sor)))])
data

#  A1 B1 VAL
#1 ao y1  10
#2 ao y1  10
#3 zo y2  55
#4 ao y2  22
#5 zo y1   0
#6 ao y1  10
#7 jo y2  44
#8 jo y2  44
#9 ko y1  20

Или мы можем получить sor в длинном формате и затем присоединиться.

library(dplyr)
sor %>%
  tidyr::pivot_longer(cols = -A1, names_to = 'B1') %>%
  right_join(data, by = c('A1', 'B1'))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...