Я пытаюсь заменить значения, соответствующие условию (меньше нуля) в одном data.frame
, значениями из другого:
> df
id val1 val2 val3
1 a 1 0 -1
2 b -1 NA 2
> replacevals
id val1 val2 val3
1 a 1 3 0
2 b 2 NA 3
Желаемый вывод:
id val1 val2 val3
1 a 1 0 0
2 b 2 NA 2
Я знаю, что два кадра данных структурированы одинаково. Я могу сделать желаемую замену, как это ...
negs <- !is.na( df ) & df < 0 # logical matrix
df[negs] <- replacevals[negs]
... но теперь классы столбцов изменились:
> sapply(df, class)
id val1 val2 val3
"character" "character" "numeric" "character"
В этом случае их можно преобразовать обратно в правильные значения путем сопоставления классов из данных замещения с окончательными данными:
df[] <- Map(`class<-`, df, sapply(replacevals, class))
Однако я работаю с некоторыми большими наборами данных и предпочитаю избегать времени, которое требуется для приведения типов. Официальная документация R рекомендует избегать этого, но я не вижу другого способа, который был бы так прост.
Матричное индексирование (x [i] с использованием логической или двухзначной целочисленной матрицы i) с использованием [не рекомендуется. Для извлечения x сначала приводится к матрице. Для замены индексы логической матрицы должны быть того же размера, что и x. Замены выполняются по одному столбцу за раз с возможными принуждениями нескольких типов.
Есть ли лучший способ сделать это?
Данные
df <- data.frame(id = c('a','b'), val1 = c(1,-1), val2 = c(0,NA),
val3 = c(-1,2), stringsAsFactors = F)
replacevals <- data.frame(id = c('a','b'), val1 = c(1,2), val2 = c(3,NA),
val3 = c(0,3), stringsAsFactors = F)