在R中合并数据帧时,我注意到了一些奇怪的行为。
合并时,我在合并的数据帧中获得额外的NA行。如果显示数据框并且不影响length()
的输出,则不会出现,但在编制索引时会变得明显。有一种解决方法,但并不是特别令人满意。我根本不会有这种奇怪的行为。
使用plyr包中的join()
会发生这种情况,并且在使用RODBC连接sql查询中的表时也可能发生这种情况。它也可能与其他软件包一起发生。
任何人都可以解释这里发生了什么,以及如何避免它?我在winXP和win8,R版本3.0.1中使用RStudio。
> library(plyr)
> # example adapted from http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html
>
> a <- as.data.frame(cbind(seq(1, 4, 1), c("Pirate", "Monkey", "Ninja", "Spaghetti")), stringsAsFactors = FALSE)
> names(a) <- c("a.id", "name")
> a
a.id name
1 1 Pirate
2 2 Monkey
3 3 Ninja
4 4 Spaghetti
>
> b <- as.data.frame(cbind(seq(1, 5, 1), c("Pirate", "Rutabaga", "Darth Vader", "Ninja", "Ninja")), stringsAsFactors = FALSE)
> names(b) <- c("b.id", "name")
> b
b.id name
1 1 Pirate
2 2 Rutabaga
3 3 Darth Vader
4 4 Ninja
5 5 Ninja
>
> z <- join(a, b, by = "name", type = "left", match = "all")
> z
a.id name b.id
1 1 Pirate 1
2 2 Monkey <NA>
3 3 Ninja 4
4 3 Ninja 5
5 4 Spaghetti <NA>
> z$compare <- ifelse(z$a.id==z$b.id, 1, 0)
> z # shows dataframe of 5 rows
a.id name b.id compare
1 1 Pirate 1 1
2 2 Monkey <NA> NA
3 3 Ninja 4 0
4 3 Ninja 5 0
5 4 Spaghetti <NA> NA
> z[z$compare==0 ,] # shows extra rows with row names of NA and NA.1
a.id name b.id compare
NA <NA> <NA> <NA> NA
3 3 Ninja 4 0
4 3 Ninja 5 0
NA.1 <NA> <NA> <NA> NA
>
> z <- z[!is.na(z$a.id),]
> z[z$compare==0 ,] # NA rows retained
a.id name b.id compare
NA <NA> <NA> <NA> NA
3 3 Ninja 4 0
4 3 Ninja 5 0
NA.1 <NA> <NA> <NA> NA
# work around to produce expected output
> z[z$compare==0 & !is.na(z$compare) ,]
a.id name b.id compare
3 3 Ninja 4 0
4 3 Ninja 5 0
答案 0 :(得分:2)
如果要提取compare
等于0
的行,则必须排除NA
个案例。
查看专栏compare
:
z$compare
[1] 1 NA 0 0 NA
当您使用比较时,即==
,NA
将导致NA
s。 @Codoremifa也在他的回答中表明了这一点。
z$compare == 0
# [1] FALSE NA TRUE TRUE NA
您应该同时执行以下操作(a)将compare
与0
进行比较,并将NA
与!is.na()
排除在一起:
z$compare == 0 & !is.na(z$compare)
# [1] FALSE FALSE TRUE TRUE FALSE
此命令仅返回TRUE
和FALSE
。
此输出可用于子集化:
z[z$compare == 0 & !is.na(z$compare), ]
# a.id name b.id compare
# 3 3 Ninja 4 0
# 4 3 Ninja 5 0
关于用于索引数据帧行的NA
的行为。
如果您使用NA
进行索引,则所有值都将被NA
替换:
z[NA, ]
# a.id name b.id compare
# NA <NA> <NA> <NA> NA
# NA.1 <NA> <NA> <NA> NA
# NA.2 <NA> <NA> <NA> NA
# NA.3 <NA> <NA> <NA> NA
# NA.4 <NA> <NA> <NA> NA
(此行为是由于向量回收。该命令与z[rep(NA, nrow(z)), ]
相同。)
如果您使用包含NA
s的索引向量,则相应的行也将仅包含NA
。
例如:
z[c(TRUE, NA, FALSE, NA, TRUE), ]
# a.id name b.id compare
# 1 1 Pirate 1 1
# NA <NA> <NA> <NA> NA
# NA.1 <NA> <NA> <NA> NA
# 5 4 Spaghetti <NA> NA
正如预期的那样,此命令返回第一行和第五行,但也返回与索引向量中的NA
对应的两个NA
行。
答案 1 :(得分:1)
您的行子集条件返回的NA既不是TRUE也不是FALSE。 NA行指的是data.frame的第二行和第五行。
例如 -
> z$compare==0
[1] FALSE NA TRUE TRUE NA
> z[NA,]
a.id name b.id compare
NA <NA> <NA> <NA> NA
NA.1 <NA> <NA> <NA> NA
NA.2 <NA> <NA> <NA> NA
NA.3 <NA> <NA> <NA> NA
NA.4 <NA> <NA> <NA> NA