R 数据框中的奇怪 "NA.123" 行
Strange "NA.123" rows in an R data frame
我在使用 R 时遇到了一个非常奇怪的问题。某些操作在数据框中生成的 NA 记录不是 "real" NA——它们在原始数据集中没有一行,即行 ID说一些奇怪的东西,比如 NA.123 而不是真正的行号,它们匹配 ==1.
的测试
很难描述正在发生的事情,所以我会让大量注释的代码来进行大部分讨论。此处引用的数据文件是来自 NHANES 2005 数据集的一个小型 (187 K) 公开可用文件,如果有人需要,可在 http://wwwn.cdc.gov/Nchs/Nhanes/2005-2006/COT_D.XPT 获得,以便他们可以尝试重现该问题。
我正在创建一个 yes/no 变量来评估可替宁血液检测是阳性还是阴性,使用 10 的截止值来定义阳性检测。在下面的代码中,我以两种不同的方式执行此操作,创建 "cotpos1" 和 "cotpos2" 来说明我在解决此问题时发现的一些内容。
就此 post 而言,"good NA" 应该是 NA,因为原始验血结果丢失,而 "bad NA" 是神秘行之一那不是原始数据的一部分,每个值都是 NA(包括 SEQN,原始数据中的任何行都没有丢失),行号显示为类似 NA.123,并且每个中的 NA列匹配 ==1.
此数据集使用名为 SEQN 的字段来标识每条记录。一开始,没有记录没有 SEQN,所以当 "bad NAs" 稍后出现并且它们的 SEQN 也为 NA(以及行中的所有其他内容)时,这向我暗示正在添加行。
我还有其他方法可以做到这一点,但不会产生 "bad NAs",比如使用 ifelse() 或使用重新编码的包,所以我的问题不是关于如何完成这项工作 -这是 "Why do the methods used in the code below produce the strange NA.123 rows?"
library(foreign) # To open SAS xpt files
# Read in the data files
testdata <- read.xport('COT_D.xpt')
################# cotpos1, everything set to 0 or 1 #################
testdata$cotpos1[testdata$LBXCOT >= 10] <- 1 # Positive cotinine test
testdata$cotpos1[testdata$LBXCOT < 10] <- 0 # Negative cotinine test
testdata$cotpos1[testdata$cotpos1==1] # We have NAs that match ==1
testdata[testdata$cotpos1==1,c("SEQN","cotpos1")] # The bad NAs have no SEQN and their row numbers look like NA.988
testdata[is.na(testdata$cotpos1),c("SEQN","cotpos1")] # The good NAs (ones that are NA because LBXCOT was NA, and match is.na()) have SEQN and row numbers
################# cotpos2, with initialization to 0 #################
testdata$cotpos2 <- 0 # Assume everyone is negative until found otherwise
testdata$cotpos2[testdata$LBXCOT >= 10] <- 1 # Positive cotinine test
# 3 tests to show we have no "bad NAs" at this point
testdata$cotpos2[testdata$cotpos2==1] # No NAs that match ==1
testdata[testdata$cotpos2==1,c("SEQN","cotpos2")] # No lines with no SEQN values or strange row IDs like NA.988
testdata[is.na(testdata$cotpos2),c("SEQN","cotpos2")] # No good NAs either because we initialized everyone to 0
# Now let's try finding the "good NA"s and setting them to NA (since they were initialized to 0, which is not accurate if the blood test results were actually missing)
testdata$cotpos2[is.na(testdata$LBXCOT)] <- NA
# Re-run the three tests, and they now show the bad NAs are back as well
testdata$cotpos2[testdata$cotpos2==1] # Now there are NAs that match ==1
testdata[testdata$cotpos2==1,c("SEQN","cotpos2")] # Now there are lines with NA SEQN values and strange row IDs like NA.988
testdata[is.na(testdata$cotpos2),c("SEQN","cotpos2")] # These are the "good NAs" only, the bad ones don't show up here
我还有其他方法可以做到这一点,但不会产生 "bad NAs",比如使用 ifelse() 或使用重新编码的包,所以我的问题不是关于如何完成这项工作 -这是 "Why do the methods used in the code above produce the strange NA.988 rows?"
响应 BondedDust 的更多信息:
感谢你的回复。你能澄清一下你指的 [] 的哪个怪癖吗?
我知道一个怪癖,如果你给它一个 NA,你会得到一个全 NA 行,例如:
b = testdata$cotpos1==1
b
testdata[b,c("SEQN","cotpos1")]
然后 b 是 NA 的任何地方我应该期望最后一行 return 是 NA。你指的是那个吗?不幸的是,在我的代码中,问题是奇怪的 NA 行出现在 b 不是 NA 的地方,所以怪癖无法解释它。
这是 b 的最后几行:
[8725] TRUE NA FALSE FALSE NA TRUE FALSE FALSE FALSE FALSE FALSE NA
[8737] FALSE NA FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE TRUE
[8749] TRUE FALSE TRUE FALSE FALSE
这是测试数据的最后几行[b,c("SEQN","cotpos1")]:
8711 41422 1
NA.986 NA NA
NA.987 NA NA
8722 41437 1
8725 41440 1
NA.988 NA NA
NA.989 NA NA
8730 41447 1
NA.990 NA NA
NA.991 NA NA
8742 41461 1
8748 41468 1
8749 41469 1
8751 41472 1
奇怪的 NA 出现在 b 不是 NA 的地方
最终编辑:
BondedDust 的回答是正确的。当我说 b 并且奇怪的 NA 不匹配时(上图),我没有考虑 [] 不打印与 FALSE 对应的行这一事实。一旦你剔除错误,它们就会完美匹配。
如果您查看 testdata$cotpos2 的值,您会看到:
> table( testdata$cotpos2==1, useNA="always")
FALSE TRUE <NA>
6346 1415 992
阅读“[”功能的帮助页面。耐读10次左右。您应该找到描述“[”在给定 NA 值时的行为的部分。 whenUnderstanding its rules and subcuties is key to effective data management in R.(我会在处理 NA 值方面以不同的方式设计它。)
我在使用 R 时遇到了一个非常奇怪的问题。某些操作在数据框中生成的 NA 记录不是 "real" NA——它们在原始数据集中没有一行,即行 ID说一些奇怪的东西,比如 NA.123 而不是真正的行号,它们匹配 ==1.
的测试很难描述正在发生的事情,所以我会让大量注释的代码来进行大部分讨论。此处引用的数据文件是来自 NHANES 2005 数据集的一个小型 (187 K) 公开可用文件,如果有人需要,可在 http://wwwn.cdc.gov/Nchs/Nhanes/2005-2006/COT_D.XPT 获得,以便他们可以尝试重现该问题。
我正在创建一个 yes/no 变量来评估可替宁血液检测是阳性还是阴性,使用 10 的截止值来定义阳性检测。在下面的代码中,我以两种不同的方式执行此操作,创建 "cotpos1" 和 "cotpos2" 来说明我在解决此问题时发现的一些内容。
就此 post 而言,"good NA" 应该是 NA,因为原始验血结果丢失,而 "bad NA" 是神秘行之一那不是原始数据的一部分,每个值都是 NA(包括 SEQN,原始数据中的任何行都没有丢失),行号显示为类似 NA.123,并且每个中的 NA列匹配 ==1.
此数据集使用名为 SEQN 的字段来标识每条记录。一开始,没有记录没有 SEQN,所以当 "bad NAs" 稍后出现并且它们的 SEQN 也为 NA(以及行中的所有其他内容)时,这向我暗示正在添加行。
我还有其他方法可以做到这一点,但不会产生 "bad NAs",比如使用 ifelse() 或使用重新编码的包,所以我的问题不是关于如何完成这项工作 -这是 "Why do the methods used in the code below produce the strange NA.123 rows?"
library(foreign) # To open SAS xpt files
# Read in the data files
testdata <- read.xport('COT_D.xpt')
################# cotpos1, everything set to 0 or 1 #################
testdata$cotpos1[testdata$LBXCOT >= 10] <- 1 # Positive cotinine test
testdata$cotpos1[testdata$LBXCOT < 10] <- 0 # Negative cotinine test
testdata$cotpos1[testdata$cotpos1==1] # We have NAs that match ==1
testdata[testdata$cotpos1==1,c("SEQN","cotpos1")] # The bad NAs have no SEQN and their row numbers look like NA.988
testdata[is.na(testdata$cotpos1),c("SEQN","cotpos1")] # The good NAs (ones that are NA because LBXCOT was NA, and match is.na()) have SEQN and row numbers
################# cotpos2, with initialization to 0 #################
testdata$cotpos2 <- 0 # Assume everyone is negative until found otherwise
testdata$cotpos2[testdata$LBXCOT >= 10] <- 1 # Positive cotinine test
# 3 tests to show we have no "bad NAs" at this point
testdata$cotpos2[testdata$cotpos2==1] # No NAs that match ==1
testdata[testdata$cotpos2==1,c("SEQN","cotpos2")] # No lines with no SEQN values or strange row IDs like NA.988
testdata[is.na(testdata$cotpos2),c("SEQN","cotpos2")] # No good NAs either because we initialized everyone to 0
# Now let's try finding the "good NA"s and setting them to NA (since they were initialized to 0, which is not accurate if the blood test results were actually missing)
testdata$cotpos2[is.na(testdata$LBXCOT)] <- NA
# Re-run the three tests, and they now show the bad NAs are back as well
testdata$cotpos2[testdata$cotpos2==1] # Now there are NAs that match ==1
testdata[testdata$cotpos2==1,c("SEQN","cotpos2")] # Now there are lines with NA SEQN values and strange row IDs like NA.988
testdata[is.na(testdata$cotpos2),c("SEQN","cotpos2")] # These are the "good NAs" only, the bad ones don't show up here
我还有其他方法可以做到这一点,但不会产生 "bad NAs",比如使用 ifelse() 或使用重新编码的包,所以我的问题不是关于如何完成这项工作 -这是 "Why do the methods used in the code above produce the strange NA.988 rows?"
响应 BondedDust 的更多信息: 感谢你的回复。你能澄清一下你指的 [] 的哪个怪癖吗?
我知道一个怪癖,如果你给它一个 NA,你会得到一个全 NA 行,例如:
b = testdata$cotpos1==1
b
testdata[b,c("SEQN","cotpos1")]
然后 b 是 NA 的任何地方我应该期望最后一行 return 是 NA。你指的是那个吗?不幸的是,在我的代码中,问题是奇怪的 NA 行出现在 b 不是 NA 的地方,所以怪癖无法解释它。
这是 b 的最后几行:
[8725] TRUE NA FALSE FALSE NA TRUE FALSE FALSE FALSE FALSE FALSE NA
[8737] FALSE NA FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE TRUE
[8749] TRUE FALSE TRUE FALSE FALSE
这是测试数据的最后几行[b,c("SEQN","cotpos1")]:
8711 41422 1
NA.986 NA NA
NA.987 NA NA
8722 41437 1
8725 41440 1
NA.988 NA NA
NA.989 NA NA
8730 41447 1
NA.990 NA NA
NA.991 NA NA
8742 41461 1
8748 41468 1
8749 41469 1
8751 41472 1
奇怪的 NA 出现在 b 不是 NA 的地方
最终编辑: BondedDust 的回答是正确的。当我说 b 并且奇怪的 NA 不匹配时(上图),我没有考虑 [] 不打印与 FALSE 对应的行这一事实。一旦你剔除错误,它们就会完美匹配。
如果您查看 testdata$cotpos2 的值,您会看到:
> table( testdata$cotpos2==1, useNA="always")
FALSE TRUE <NA>
6346 1415 992
阅读“[”功能的帮助页面。耐读10次左右。您应该找到描述“[”在给定 NA 值时的行为的部分。 whenUnderstanding its rules and subcuties is key to effective data management in R.(我会在处理 NA 值方面以不同的方式设计它。)