0

所以我试图从 5 个不同的列中制作 3 个主列。我正在研究 2 种不同的医学测试(TestA 和 TestB)。我查看了其他一些关于制作新行的答案,但在有多个条件和使用分类值时找不到答案。

目前我有以下列: TestA2009 TestA2010 TestA2011 TestB2010 TestB2011

我最终想要的三列是: 1. 参加过TestA(任何年份)但从未参加过TestB 的人 2. 参加过TestB(任何年份)但从未参加过TestA 的人 3. 参加过TestA(任何年份)的人)和TestB(任何年份)

TestA 的值包括 NA、Positive、Negative、Not Reported 等。TestB 的
值包括 NA、Reactive、Unsatisfactory 等。

NA 表示他们没有进行测试。

希望这个问题很清楚。非常感谢 - 我是 R 的新手,可以使用我能得到的所有帮助!

编辑:感谢大家的建议。我自己也尝试过这种方法。我将所有“NA”切换为“0”,将所有其他值切换为“1”。是否有意义?

TestA <-ifelse(TestA2009==1 | TestA2010==1 | TestA2011==1, "TESTa", "NOtesta")
TestB <-ifelse(TestB2010==1 | TestB2011==1, "TESTb", "NOtestb")

TestAonly <-(TestA==TESTa & TestB=="NOtestb")
TestAandTestB <-(TestA==TESTa & TestB=="TESTb")
4

2 回答 2

1

应该差不多是这样。调用您的数组mydata,然后通过非常简单的步骤,

notA <- is.na(mydata[,1])*is.na(mydata[,2])*is.na(mydata[,3])
notB <- is.na(mydata[,4])*is.na(mydata[,5])
AandNotB<- !notA*notB
BandNotA <- notA*!notB
AandB <-!notA*!notB

mydata<-cbind(mydata,AandNotB,BandNotA,AandB)

我假设除此之外的任何值NA都是积极的情况。

于 2013-06-17T18:29:12.653 回答
0

一个可重现的例子:

vals1 <- c(NA, "pos", "neg", "nr")
set.seed(1)
df1 <- data.frame(
    id = seq(1:10),
    a09 = sample(vals1,10,replace=TRUE),
    a10 = sample(vals1,10,replace=TRUE),
    a11 = sample(vals1,10,replace=TRUE),
    b10 = sample(vals1,10,replace=TRUE),
    b11 = sample(vals1,10,replace=TRUE)
    )
### modify to give at least one case meeting each of your criteria
df1[10,c(5,6)] <- NA # 2x NAs for b's
df1[1,c(2,3,4)] <- NA # 3x NAs for a's
df1[2,c(2,4,5,6)] <- NA # all NAs

给予:

   id  a09  a10  a11  b10  b11
1   1 <NA> <NA> <NA>  pos   nr
2   2 <NA> <NA> <NA> <NA> <NA>
3   3  neg  neg  neg  pos   nr
4   4   nr  pos <NA> <NA>  neg
5   5 <NA>   nr  pos   nr  neg
6   6   nr  pos  pos  neg   nr
7   7   nr  neg <NA>   nr <NA>
8   8  neg   nr  pos <NA>  pos
9   9  neg  pos   nr  neg  neg
10 10 <NA>   nr  pos <NA> <NA>

现在我们链接多个逻辑运算符来获取有问题的 id。这不像上面的@Carls 建议那么优雅,但乍一看可能更直观......请注意分组括号,即a and (b or c)

### test a not b, id=10 
df1$id[ is.na(df1$b10) & is.na(df1$b11) & 
  ( !is.na(df1$a09) | !is.na(df1$a10) | !is.na(df1$a11) ) ]

### test b not a, id=1
df1$id[ is.na(df1$a09) & is.na(df1$a10) & is.na(df1$a11) &
  & ( !is.na(df1$b10) | !is.na(df1$b11) ) ]

最后一个示例使用了在传递给期望数字的方法时R将转换TRUE为的事实。1在这种情况下,我们要检查该行中的所有 5 个值是否NA然后使用否定(表示 NOT)获取其他行。!

### a and b, id= all except no. 2
df1$id[!rowSums(is.na(df1[ ,2:6]))==5]

快速介绍逻辑运算符:这里这里

更新

我不确定您为什么要摆脱NAs ,因为上述所有建议都适用于它们。首先,保持NA并遵循您的表达方式:

TestA <-ifelse( !is.na(df1$a09) | !is.na(df1$a10) | !is.na(df1$a11), "TESTa","NOtesta")
TestB <-ifelse( !is.na(df1$b10) | !is.na(df1$b11), "TESTb", "NOtestb")

TestAonly <- (TestA=="TESTa" & TestB=="NOtestb")
TestAandTestB <- (TestA=="TESTa" & TestB=="TESTb")

请注意,您需要在 eg 周围加上引号Testa,否则R会尝试将其作为变量而不是字符串文字来查找。您也可以考虑为变量采用更简单的命名约定/样式,例如dot.seperator

结果将是一个与 长度相同的逻辑向量nrow(df1)

如果您坚持使用10使用以下内容:

TestB <-ifelse( df1$b10==1 | df1$b11==1, "TESTb", "NOtestb" )
于 2013-06-17T18:44:29.663 回答