Для каждой строки замените значения из указанных c столбцов (определенных другим фреймом данных) на значение из вектора - PullRequest
3 голосов
/ 20 июня 2020

Допустим, у нас есть:

set.seed(42)
df1 <- data.frame(v1=rnorm(10) , v2=rnorm(10), v3=rnorm(10), v4=rnorm(10))

, а также

df2 <- data.frame(v1=rnorm(10) , v2=rnorm(10), v3=rnorm(10), v4=rnorm(10))
vector <- c(17,21,33,41,50,63,72,81,91,10)

df1 и df2 имеют одинаковые имена столбцов, а df2 генерируется обработкой df1.

Для каждой строки в df2 я хотел бы заменить значение, которое соответствует условию < 0.5 в df1, на соответствующее значение вектора.

Например, если какой-либо из столбцов первой строки в df1 имеет значение ниже 0,5, тогда соответствующий столбец (столбцы) первой строки в df2 необходимо будет заменить первым элементом вектора, то есть 17. Для второй строки они будут заменены на 21 et c.

Я представляю себе apply, и пользовательская функция могла бы помочь, но я не могу понять это. Заранее благодарим за решение.

Ответы [ 2 ]

3 голосов
/ 20 июня 2020

1)

Мой подход был:

idx <- df1 < .5
tmp <- idx * vector
df2[idx] <- tmp[idx]

2)

Второй вариант, предоставляемый @ MartinGal в комментариях:

df2 * (df1>=0.5) + (df1<0.5) * vector

Результат

df2
#           v1            v2          v3         v4
#1  -1.4936251  5.676206e-01 -0.08610730 17.0000000
#2  21.0000000  2.100000e+01 -0.88767902 21.0000000
#3  33.0000000  6.288407e-05 33.00000000 33.0000000
#4  41.0000000  1.122890e+00 -0.02944488 41.0000000
#5  50.0000000  5.000000e+01 50.00000000 50.0000000
#6  -0.4282589  6.300000e+01 63.00000000 63.0000000
#7  72.0000000  7.200000e+01 72.00000000 72.0000000
#8  81.0000000  8.100000e+01 81.00000000 -0.8002822
#9  -1.2247480  9.100000e+01 91.00000000 91.0000000
#10  0.1795164 -5.246948e-02 10.00000000 10.0000000

Сначала мы проверяем, в каких позициях df1 равно < .5, и умножаем это на vector, чтобы получить эту матрицу

idx <- df1 < .5
tmp <- (idx) * vector
tmp
#      v1 v2 v3 v4
# [1,]  0  0  0 17
# [2,] 21 21  0 21
# [3,] 33  0 33 33
# [4,] 41  0  0 41
# [5,] 50 50 50 50
# [6,]  0 63 63 63
# [7,] 72 72 72 72
# [8,] 81 81 81  0
# [9,]  0 91 91 91
#[10,]  0  0 10 10

Это значения, которые вы хотите вставить в df2 в позиция, где idx равно TRUE.

Таким образом, следующим шагом будет замена этих значений в df2 с использованием логической матрицы, т.е. idx:

df2[idx] <- tmp[idx]
1 голос
/ 20 июня 2020

Мы также можем использовать Map из base R

data.frame(Map(function(x, y) ifelse(x < 0.5, vector, y) , df1, df2))

Или используя map2 из purrr

library(purrr)
map2_df(df1, df2, ~ case_when(.x < 0.5 ~  vector, TRUE~ .y))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...