新手:我有一个包含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中的最佳方法和语法。思想赞赏。
答案 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.grid
和factor
。
首先,为三列创建我们将具有“是”和“否”的所有组合。
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。我希望这就是你想要的。