R中的复杂合并以标记不匹配的观测值?

R中的复杂合并以标记不匹配的观测值?,r,function,merge,append,apply,R,Function,Merge,Append,Apply,我正在尝试将两个数据集连接在一起。叫他们x和y。我相信y中的ID变量是x中ID变量的子集。但不是纯粹意义上的,因为我知道x包含的id比y多,但我不知道映射。也就是说,x和y中的一些(但不是全部)id可以1:1匹配 我的最终目标是找出1:1映射失败的地方,并标记这些观察结果。我原以为合并是一条路,但也许不是。一个例子如下: id <- c(1:10, 1:100) X1 <- rnorm(110, mean = 0, sd = 1) year <- c("2004","2005

我正在尝试将两个数据集连接在一起。叫他们x和y。我相信y中的ID变量是x中ID变量的子集。但不是纯粹意义上的,因为我知道x包含的id比y多,但我不知道映射。也就是说,x和y中的一些(但不是全部)id可以1:1匹配

我的最终目标是找出1:1映射失败的地方,并标记这些观察结果。我原以为合并是一条路,但也许不是。一个例子如下:

id <- c(1:10, 1:100)

X1 <- rnorm(110, mean = 0, sd = 1)
year <- c("2004","2005","2006","2001","2002") 
year <- rep(year, 22)

month = c("Jul","Aug","Sep","Oct","Nov","Dec","Jan","Feb","Mar","Apr")
month <- rep(month, 11)

#dataset X
x <- cbind(id, X1, month, year)

#dataset Y
id2 <- c(1:10, 200)
Y1 <- rnorm(11, mean = 0 , sd = 1)
y <- cbind(id2,Y1)

#merge on the IDs; but we get an error because when id2 == 200 in y we don't 
#have a match in x 
result <- merge(x, y, by.x="id", by.y = "id2", all =TRUE)
这次合并使事情比我预想的要复杂。我希望我能检查x中的每一个观察结果,找出y中id与id2匹配的位置,并标记那些不匹配的。所以我会得到一个新的向量,称之为flag,如果x$id在y$id2中有匹配项,那么它的值为1,否则为零。这样,我就可以知道1:1映射在哪里失败了。通过重新编码NAs,我可能会在这方面取得一些进展,但是当id2==200时抛出的错误呢?它只是丢弃信息

我尝试过按行追加,但运气不佳,看起来我也应该放弃合并,也许最好是编写一个循环或函数来执行以下操作:

对于x中的每个观测值

id2=哪个(id2)对应于id月份年

如果上述长度为==1,则标志=1,否则为0

等等


希望这一切都有意义。我将非常感谢任何帮助或指导

如果您正在查找
x$id
中的哪些内容在
y$id2
中,那么您可以使用

x$id %in% y$id2
获取返回匹配项的逻辑向量。然而,它并不保证一对一的通信;只是一对多。然后可以将该向量添加到数据帧中

x$match.y <- x$id %in% y$id2
筛选出在
y$id2
中多次出现的元素。您还可以将其添加到
x

x$match.y.unique <- (x$id %in% y$id2) & !(x$id %in% y$id2[duplicated(y$id2)])

x$match.y.unique合并失败的原因是为x和y提供了两种不同的结构(一种是数字矩阵,另一种是字符矩阵)。当
数据时使用
cbind
。应选择帧
,这是常见的故障策略

> str(x)
 chr [1:110, 1:4] "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "1" "2" ...
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr [1:4] "id" "X1" "month" "year"
> str(y)
 num [1:11, 1:2] 1 2 3 4 5 6 7 8 9 10 ...
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr [1:2] "id2" "Y1"
如果您使用了
data.frame
功能(因为数据帧是
merge
应该使用的),那么它会成功:

> x <- data.frame(id, X1, month, year); y <- data.frame(id2,Y1)
> str( result <- merge(x, y, by.x="id", by.y = "id2", all =TRUE) )
'data.frame':   111 obs. of  5 variables:
 $ id   : num  1 1 2 2 3 3 4 4 5 5 ...
 $ X1   : num  1.5063 2.5035 0.7889 -0.4907 -0.0446 ...
 $ month: Factor w/ 10 levels "Apr","Aug","Dec",..: 6 6 2 2 10 10 9 9 8 8 ...
 $ year : Factor w/ 5 levels "2001","2002",..: 3 3 4 4 5 5 1 1 2 2 ...
 $ Y1   : num  1.449 1.449 -0.134 -0.134 -0.828 ...

> tail( result <- merge(x, y, by.x="id", by.y = "id2", all =TRUE) )
     id         X1 month year        Y1
106  96 -0.3869157   Dec 2004        NA
107  97  0.6373009   Jan 2005        NA
108  98 -0.7735626   Feb 2006        NA
109  99 -1.3537915   Mar 2001        NA
110 100  0.2626190   Apr 2002        NA
111 200         NA  <NA> <NA> -1.509818

>x
cbind
创建矩阵,而不是数据帧。您对创建
x
y
的调用应该是
x您将得到
y$id2==1
的两个观察值,因为
x
中有两行
x$id==1
。如果合并看到多个符合联接条件的观测值,它将为每个可能的组合创建一行。这是经过设计的,非常有用。
duplicated
返回布尔向量。您需要
y$id2[重复(y$id2)]
立即启动!我意识到我的错误,花了几分钟在编辑屏幕上试图记住正确的语法。谢谢你的接球,谢谢!当y$id2==200并且在x$id中没有匹配项时,此选项似乎不起作用。它应该为false,但结果为true:
测试我在解决方案中提出的向量是一个逻辑向量,告诉
x$id
的哪些元素可以唯一地、以1对1的方式与
y$id2
的元素匹配。考虑<代码> x $ ON.to.1,我不认为<代码>数据。框架(x,y,test)< /> >按你的想法去做。
data.frame
命令只是将其参数混合在一起,而不是通过
id
进行合并。此外,由于在本例中,
y
的行数少于
x
,因此它将被重复10次。
x$match.y.unique <- (x$id %in% y$id2) & !(x$id %in% y$id2[duplicated(y$id2)])
> str(x)
 chr [1:110, 1:4] "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "1" "2" ...
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr [1:4] "id" "X1" "month" "year"
> str(y)
 num [1:11, 1:2] 1 2 3 4 5 6 7 8 9 10 ...
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr [1:2] "id2" "Y1"
> x <- data.frame(id, X1, month, year); y <- data.frame(id2,Y1)
> str( result <- merge(x, y, by.x="id", by.y = "id2", all =TRUE) )
'data.frame':   111 obs. of  5 variables:
 $ id   : num  1 1 2 2 3 3 4 4 5 5 ...
 $ X1   : num  1.5063 2.5035 0.7889 -0.4907 -0.0446 ...
 $ month: Factor w/ 10 levels "Apr","Aug","Dec",..: 6 6 2 2 10 10 9 9 8 8 ...
 $ year : Factor w/ 5 levels "2001","2002",..: 3 3 4 4 5 5 1 1 2 2 ...
 $ Y1   : num  1.449 1.449 -0.134 -0.134 -0.828 ...

> tail( result <- merge(x, y, by.x="id", by.y = "id2", all =TRUE) )
     id         X1 month year        Y1
106  96 -0.3869157   Dec 2004        NA
107  97  0.6373009   Jan 2005        NA
108  98 -0.7735626   Feb 2006        NA
109  99 -1.3537915   Mar 2001        NA
110 100  0.2626190   Apr 2002        NA
111 200         NA  <NA> <NA> -1.509818