基于R中其他列中的数据的条件计算

时间:2013-09-09 09:00:49

标签: r

新手:我有一个包含3列分类值的数据表,我想添加第四列,其中的值根据前3列的值按行计算。到目前为止,我有:

tC <- textConnection("Visit1    Visit2  Visit3
yes no  no
yes no  yes
yes yes yes")
data1 <- read.table(header=TRUE, tC)
close.connection(tC)
rm(tC)
data1["pattern"] <- NA

接下来我想填写第4列,以便如果visit1,visit2和visit3的值为例如“yes”,“no”和“no”,则NA将在模式中替换为“1”该行的列。在其他语言中,这将是带有一些IF语句的FOR循环。我看过应用系列,但仍然不太确定R中的最佳方法和语法。思想赞赏。

3 个答案:

答案 0 :(得分:3)

我不确定这是解决此问题的最有效方法,但我们可以找到唯一的行,然后在data.frame中找到它匹配的唯一行中的每一行。因此,该数字是模式ID。我们必须将行折叠成单个字符串元素,否则R矢量化会妨碍我们想要的方式。以下示例使用稍微扩展的示例数据:

#  Visit1 Visit2 Visit3
#1    yes     no     no
#2    yes     no    yes
#3    yes    yes    yes
#4     no    yes     no
#5    yes     no    yes

#  Get unique combinations
pats <- unique( data1 )

#  Colapse each row to a single string element
pats <- apply( pats , 1 , paste , collapse = " " )

#do the same to your data and compare with the patterns
data1$pattern <- apply( data1 , 1 , function(x) match( paste( x , collapse = " " ) , pats ) )
#  Visit1 Visit2 Visit3 pattern
#1    yes     no     no       1
#2    yes     no    yes       2
#3    yes    yes    yes       3
#4     no    yes     no       4
#5    yes     no    yes       2

答案 1 :(得分:2)

假设我们正在使用@ SimonO101的扩展样本数据,我建议expand.gridfactor

首先,为三列创建我们将具有“是”和“否”的所有组合。

facLevs <- expand.grid(c("yes", "no"), c("yes", "no"), c("yes", "no"))
facLevs
#   Var1 Var2 Var3
# 1  yes  yes  yes
# 2   no  yes  yes
# 3  yes   no  yes
# 4   no   no  yes
# 5  yes  yes   no
# 6   no  yes   no
# 7  yes   no   no
# 8   no   no   no

现在,我们将考虑列的组合。我们可以使用do.call(paste, ...)apply(mydf, ...)更轻松地执行此操作。我们会将其转换为as.numeric以获取数字组。

mydf$pattern <- as.numeric(factor(do.call(paste, mydf[1:3]), 
                                  do.call(paste, facLevs)))
mydf
#   Visit1 Visit2 Visit3 pattern
# 1    yes     no     no       7
# 2    yes     no    yes       3
# 3    yes    yes    yes       1
# 4     no    yes     no       6
# 5    yes     no    yes       3

如您所见,pattern = 7对应于我们在facLevs data.frame的第七行找到的值。


为方便起见,这里是mydf

mydf <- structure(list(Visit1 = c("yes", "yes", "yes", "no", "yes"), 
                       Visit2 = c("no", "no", "yes", "yes", "no"), 
                       Visit3 = c("no", "yes", "yes", "no", "yes")), 
                  .Names = c("Visit1", "Visit2", "Visit3"), 
                  class = "data.frame", row.names = c("1", "2", "3", "4", "5"))

答案 2 :(得分:0)

<强>更新

回答周期:

updateRow <- function(rIndex, data1) { 
  if ((data1[rIndex, 1] == "yes") && 
      (data1[rIndex, 2] == "no") && 
      (data1[rIndex, 3] == "no")) { 
        data1[rIndex, 4] <- 1
  }   
}

for (i in c(1:3)) updateRow(i, data1); # dim(data1)[2]-1 the column number if you need to change it.

您可以根据需要更改if。我希望这就是你想要的。