Выделить, если два значения из разных столбцов приходят альтернативно

#r

#r

Вопрос:

для меня это немного сложно, поэтому допустим, у меня есть фрейм данных, как показано ниже

 |ID1|ID2|T/F|
|---|---|---|
|653|385|0|
|844|610|0|
|240|970|1|
|970|240|1|
|826|551|0|
|872|854|0|
|556|460|0|
|440|490|0|
  

итак, у нас есть два столбца ID1 и ID2, и я хочу изменить «T / F» на 1/0
если какие-либо два значения в циклических ссылках друг на друга, например, ID 970, сообщите ID 240
в следующей строке снова 240 сообщают о 970. вид циклической ссылки. если это произойдет в любой строке, измените T / F на 1, иначе 0

введите описание изображения здесь

Ответ №1:

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

 match(x$ID1, x$ID2) == match(x$ID2, x$ID1)
#[1]   NA   NA TRUE TRUE   NA   NA   NA   NA
  

Или с помощью interaction with %in% .

  (interaction(x) %in% interaction(rev(x)))
#[1] 0 0 1 1 0 0 0 0
  

Данные:

 x <- data.frame(ID1=c(653,844,240,970,826,872,556,440),
 ID2=c(385,610,970,240,551,854,460,490))
  

Ответ №2:

Одним из способов было бы объединить фрейм данных с самим собой, чтобы найти циклическое соответствие.

 library(dplyr)
df %>%
  inner_join(df, by = c('ID1' = 'ID2')) %>%
  right_join(df, by = c('ID1', 'ID2')) %>%
  mutate(TF =  (!is.na(ID1.y))) %>%
  select(-ID1.y)

#  ID1 ID2 TF
#1 653 385  1
#2 240 970  1
#3 970 240  1
#4 385 653  1
#5 844 610  0
#6 826 551  0
#7 872 854  0
#8 556 460  0
#9 440 490  0
  

Это может быть записано в базе R как :

 transform(merge(merge(df, df, by.x = 'ID1', by.y = 'ID2'), 
          df, all.y = TRUE), TF =  (!is.na(ID1.y)))
  

данные

Добавлена дополнительная строка в данные, чтобы включить еще одно совпадение.

 df <- structure(list(ID1 = c(653, 844, 240, 970, 826, 872, 556, 440, 
385), ID2 = c(385, 610, 970, 240, 551, 854, 460, 490, 653)), row.names = c(NA, 
-9L), class = "data.frame")
df

#  ID1 ID2
#1 653 385
#2 844 610
#3 240 970
#4 970 240
#5 826 551
#6 872 854
#7 556 460
#8 440 490
#9 385 653
  

Редактировать

Для фактического набора данных нам может потребоваться изменить имена столбцов.

 df5 %>%
  inner_join(df5, by = c("ID 1" = "ID 2")) %>%
  right_join(df5, by = c("ID 1" , "ID 2")) %>%
  mutate(TF =  (!is.na(`ID 1.y`))) %>%
  select(-`ID 1.y`)
  

Комментарии:

1. когда я использую подобное, возникает ошибка df5 <- structure(список( ID 1 = c(653, 844, 240, 970, 826, 872, 556, 440, 385), ID 2 = c(385, 610, 970, 240, 551, 854, 460, 490, 653)), row.names = c(NA, -9L), class = «data.frame») df %>% inner_join(df, by = c(‘ID 1’ = ‘ID 2’)) %>% right_join(df, by = c(‘ID 1’, ‘ID 2’)) %>% mutate(TF = (!is.na ( ID 1.y ))) %>% выбрать(- ID1.y )

2. @user14176250 Вам нужно изменить имена столбцов в соответствии с вашими столбцами. Обычно лучше не иметь пробелов в именах столбцов. Смотрите часть редактирования в обновленном ответе.

Ответ №3:

Вот igraph решение

 library(igraph)

df <- within(
  df,
  TF <-  (degree(graph_from_data_frame(df), as.character(ID1)) > 1)
)
  

что дает

 > df
  ID1 ID2 TF
1 653 385  0
2 844 610  0
3 240 970  1
4 970 240  1
5 826 551  0
6 872 854  0
7 556 460  0
8 440 490  0