Может ли кто-нибудь объяснить сообщение «неожиданное» = «» в моей функции semi_join в R, когда я использую относительные ссылки? - PullRequest
0 голосов
/ 03 января 2019

Я пытаюсь построить скрипт на R, который будет объединяться в разные поля на основе ввода пользователя. Я использую версию 0.7.6 dplyr через tidyverse (1.2.1).

Я мог бы построить несколько, в основном, одинаковых операторов соединения и ссылаться на разные, основываясь на вводе, но это выглядит не элегантно. Ниже приведен пример с комментариями под этим. Я все еще новичок в R, поэтому я прошу прощения, если это само по себе неэлегантно:

library(tidyverse)
df <- tibble(
  a = letters[1:20],
  b = c(1:5,1:5,1:5,1:5)
)

ref <- tibble(
  let_ref_col = c('e','g','b','d','f'),
  num_ref_col = c(2,4,NA,NA,NA)
)

df2 <- semi_join(df,ref,c('b'='num_ref_col'))

df3 <- semi_join(df,ref,c('b'=colnames(ref)[2]))
df2==df3 #just to check

df4 <- semi_join(df,ref,c(colnames(df)[2]=colnames(ref)[2]))

df2 вернет 8 строк, где столбец b в df равен 2 или 4.

R, кажется, не возражает против того, чтобы я обобщил имя второй переменной соединения, о чем свидетельствует `df3.

Когда я пытаюсь применить ту же самую логику к первой переменной, я получаю сообщение об ошибке от df4:

Error: unexpected '=' in "df4 <- inner_join(df,ref,c(colnames(df)[2]="

Я бы хотел иметь возможность иметь относительную ссылку для обоих полей, если это возможно. Что-то вроде:

JOIN_DESIRED <- 2
df5 <- semi_join(df,ref,c(colnames(df)[JOIN_DESIRED] = colnames(ref)[JOIN_DESIRED])

Который может быть изменен на 1, чтобы соединяться буквами вместо цифр

Ответы [ 2 ]

0 голосов
/ 08 января 2019

Вы делаете много вещей в одной строке с вашей последней строкой semi_join(df,ref,c(colnames(df)[2]=colnames(ref)[2])). В частности, в этом бите: colnames(df)[2]=colnames(ref)[2] есть много операций, которые могут работать против логики ленивого выполнения R . Вот как я могу запрограммировать это:

library(tidyverse)

df <- tibble(
  a = letters[1:20],
  b = c(1:5,1:5,1:5,1:5)
)

ref <- tibble(
  let_ref_col = c('e','g','b','d','f'),
  num_ref_col = c(2,4,NA,NA,NA)
)

semi_join_by_column_index <- function(df1, df2, idx) {
  original_name <- names(df1)[idx]

  names(df1)[idx] <- "join_column"
  names(df2)[idx] <- "join_column"

  new_df <- semi_join(df1, df2, by = "join_column")

  new_idx <- match("join_column", names(new_df))
  names(new_df)[new_idx] <- original_name

  return(new_df)
}

merged_df <- semi_join_by_column_index(df, ref, idx = 2)
0 голосов
/ 03 января 2019

Вот обходной путь.Мы можем использовать names<- для присвоения имен.

df4 <- semi_join(df, ref, `names<-`(colnames(ref)[2], colnames(df)[2]))

identical(df2, df4)
# [1] TRUE

identical(df3, df4)
# [1] TRUE
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...