сравнить несколько значений с несколькими значениями в R Dataframe - PullRequest
1 голос
/ 03 мая 2020

У меня есть фрейм данных с 2 столбцами: «время» и «a».

df <- data.frame(time = c(1, 2, 3, 4, 5, 6, 7, 8, 9), a = c(3, 8, 2, 2, 2, 2, 2, 4, 5))

Как можно сравнивать, если значения менялись со временем? Мне нужен новый столбец «comp» в фрейм данных, который показывает, является ли третье значение в столбце "c" тем же, что и последние два значения и два предыдущих значения в одном и том же столбце. Таким образом, результат может выглядеть следующим образом:

df <- data.frame(time = c(1, 2, 3, 4, 5, 6, 7, 8, 9), a = c(3, 8, 2, 2, 2, 2, 2, 4, 5), comp = c(F, F, F, F, T, F, F, F, F)

В конце мне нужно сравнить колонку с примерно 3 млн. Наблюдений.

Ответы [ 3 ]

3 голосов
/ 03 мая 2020

Использование тидиверса:

library(tidyverse)

df %>% 
  arrange(time) %>% 
  mutate(comp = a == lag(a) & a == lag(a, 2) & a == lead(a) & a == lead(a, 2))

#   time a  comp
# 1    1 3 FALSE
# 2    2 8 FALSE
# 3    3 2 FALSE
# 4    4 2 FALSE
# 5    5 2  TRUE
# 6    6 2 FALSE
# 7    7 2 FALSE
# 8    8 4 FALSE
# 9    9 5 FALSE
1 голос
/ 03 мая 2020

Аналогичное решение @Bas с использованием data.table

library(data.table)
setDT(df)[, comp := a == shift(a) & a == shift(a, 2) & 
                  a == shift(a, type = 'lead') & a == shift(a, 2, type = 'lead')]

#   time a  comp
#1:    1 3 FALSE
#2:    2 8 FALSE
#3:    3 2 FALSE
#4:    4 2 FALSE
#5:    5 2  TRUE
#6:    6 2 FALSE
#7:    7 2 FALSE
#8:    8 4 FALSE
#9:    9 5 FALSE
1 голос
/ 03 мая 2020

Если я правильно понял, вы ищете значения, которые совпадают с их 2 смежными значениями с обеих сторон, и в этом случае вы будете рады игнорировать «пропущенные» смежные значения для 2 первых и 2 последних ценности.

Использование базы R:

sameasadj=function(v,n=2,include_ends=T) {
    if(include_ends){vv=c(rep(head(v,1),n),v,rep(tail(v,1),n))} 
    else {vv=c(rep(NA,n),v,rep(NA,n))}
    sapply(seq_along(v),function(i) diff(range(vv[i:(i+2*n)]))==0)
}

df$comp = sameasadj(df$a)
df$comp

Вывод:

[1] FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE

Объяснение:

sameasadj=function(v,n=2,include_ends=T) = определить функцию sameasadj, чтобы проверить, является ли каждое значение совпадает с соседними соседями с каждой стороны. Мы можем дать возможность выбрать число n соседних соседей (в вашем случае 2) и включать или не включать концы (или возвращать 'NA' для них, поскольку у них недостаточно соседей на одной стороне).

if(include_ends){vv=c(rep(head(v,1),n),v,rep(tail(v,1),n))} = если мы хотим включить концы, то мы просто добавляем «отсутствующие» соседи, чтобы они соответствовали

else {vv=c(rep(NA,n),v,rep(NA,n))} = в противном случае мы добавляем значения «NA»

sapply(seq_along(v),function(i) = go вдоль каждой позиции i в векторе ...

diff(range(vv[i:(i+2*n)]))==0) = ... и проверьте, все ли элементы от i до i + 2 * n являются то же самое (diff(range(x))==0 вернет TRUE, если все элементы x одинаковы)

Поместив все это в функцию, вы сможете позже передумать о количестве соседних соседей или о том, что делать с концами ...

...