R中的新列基于许多条件

时间:2013-06-17 17:43:24

标签: r conditional-statements categorical-data

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

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

我最终想要的三个栏目是: 1.那些参加TestA(任何一年)但从未参加过TestB的人 2.那些参加过TestB(任何一年)但从未参加过TestA的人 3.参加TestA(任何一年)和TestB(任何一年)的人

TestA的值包括NA,正面,负面,未报告等。
TestB的值包括NA,Reactive,Unsatisffactory等等。

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")

2 个答案:

答案 0 :(得分: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以外的任何值都是正值。

答案 1 :(得分: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]

快速介绍逻辑运算符:herehere

<强>更新

我不确定为什么你摆脱NA s,因为上述所有建议都适用于他们。 首先,坚持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")

请注意,您需要引用例如Testa,否则R会尝试将其视为变量而不是字符串文字。您也可以考虑对变量采用更简单的命名约定/样式,例如dot.seperator

结果将是与nrow(df1)具有相同长度的逻辑向量。

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

TestB <-ifelse( df1$b10==1 | df1$b11==1, "TESTb", "NOtestb" )