a <- c(1,45,90,115,170,203,259)
b <- c(35,60,110,145,190,231,270)
df <- data.frame(a,b)
c <- c(27,175, 230)
Я хотел бы вставить значения c
в df
, и положение в строке значений должно зависеть от того, где они находятся между значениями столбца a
и b
. Например. c[2]
(175) должно появиться в той же строке, что и a = 170 & b = 190, 230 должно находиться в той же строке, что и a = 203 b = 270, и т. Д.
c
содержит меньше значений, чем df
, поэтому ячейки могут быть NA
.
Я нигде не могу найти на это ответа. Лучшее, что я нашел, - это функция roll = nearest
в таблицах данных, но она не допускает условия «не больше».
Я мог бы использовать цикл for, однако данные велики, так что это был бы ресурсный метод.
У кого-нибудь есть идеи? Спасибо.
3 ответа
Используйте findInterval()
для определения действительных индексов
aidx = findInterval(c, df$a)
bidx = findInterval(c, df$b) + 1
keep = aidx == bidx
Затем обновите исходный фрейм данных
df[aidx[keep], "c"] = c[keep]
Я ожидал, что это будет быстро до 100 миллионов строк, если строки data.frame уже отсортированы.
Если вы хотите, чтобы это происходило быстро, вы можете попробовать non-equi
функцию присоединения в data.table
версии 1.9.7
:
library(data.table)
v <- c(27, 175, 230)
v_dt <- data.table(id = v, c = v) # create a data table with an identical column to
# join with df
v_dt[setDT(df), .(a, b, c), on = .(id > a, id < b), allow = T]
# a b c
#1: 1 35 27
#2: 45 60 NA
#3: 90 110 NA
#4: 115 145 NA
#5: 170 190 175
#6: 203 231 230
#7: 259 270 NA
Если у вас нет data.table
1.9.7
, вы можете использовать foverlaps
. Параметр по умолчанию type
- any
, что означает, что если значение в [id, c]
из v_dt
имеет какое-либо перекрытие с диапазоном [a, b]
из df
, они будут совпадать, поскольку id == c
для каждой строки, это эквивалентно тому, что id
попадает в диапазон:
setkey(v_dt, id, c)
setkey(df, a, b)
foverlaps(df, v_dt)[, id := NULL][,.(a, b, c)]
# a b c
#1: 1 35 27
#2: 45 60 NA
#3: 90 110 NA
#4: 115 145 NA
#5: 170 190 175
#6: 203 231 230
#7: 259 270 NA
Вот решение с использованием базы R.
#sample data
a <- c(1,45,90,115,170,203,259)
b <- c(35,60,110,145,190,231,270)
df <- data.frame(a,b)
c <- c(27,175, 230)
#Solution
#create place holder column
df$c<-NA
#find rows where the elements of c will fit
location<-which(c > df$a & c<df$b)
#update dataframe
df$c[location]<-c
Команда which выдаст кучу предупреждений, но это не имеет значения. Это решение будет работать только в том случае, если существует 1 и единственное решение для каждого элемента в векторе c.
Похожие вопросы
Новые вопросы
r
R — это бесплатный язык программирования с открытым исходным кодом и программная среда для статистических вычислений, биоинформатики, визуализации и общих вычислений. Пожалуйста, используйте минимально воспроизводимые примеры, которые другие могут запустить с помощью копирования и вставки. Показать желаемый результат полностью. Используйте dput() для данных и укажите все небазовые пакеты с помощью library(). Не вставляйте изображения для данных или кода, вместо этого используйте блоки кода с отступом. Для вопросов по статистике используйте https://stats.stackexchange.com.