我有这段代码在数据框中添加新列:
for(i in 1:length(listParms))
{
parm = as.character(listParms[i])
lParm = paste0(parm,"_LOG")
dataSubset[,lParm] = apply(dataSubset,1, function(row){
if(parm %in% names(dataSubset)){
if(grep("0",row[parm],fixed=T) >= 0) 0
else NA
}
else NA
})
}
listParms是要添加到dataSubset data.frame的新列的列表。
我收到以下错误:
Error in if (grep("0", row[parm], fixed = T) >= 0) 0 :
argument is of length zero
listParms包含类似:“PARM1”,“PARM2”,“PARM3”,“PARM4”,“PARM5” dataSubset是一个data.frame,如:
MATERIAL TEST_SEQ PARM1 PARM2 PARM3 PARM4 PARM5
Math 1 0001 0010 0100 0000
Math 2 1100 1110 1111 1200 0200
Math 3 2211 1022 2112 1202
Science 1 1112 0111 0110 0011 2001
Science 2 0122 2111 1222 0022 2010
欲望输出:
MATERIAL TEST_SEQ PARM1 PARM2 PARM3 PARM4 PARM5 PARM1_LOG PARM2_LOG PARM3_LOG PARM4_LOG PARM5_LOG
Math 1 0001 0010 0100 0000 0 0 0 NA 0
Math 2 1100 1110 1111 1200 0200 0 0 NA 0 0
Math 3 2211 1022 2112 1202 NA NA 0 NA 0
Science 1 1112 0111 0110 0011 2001 NA 0 0 0 0
Science 2 0122 2111 1222 0022 2010 0 NA NA 0 0
任何人都可以帮我理解为什么吗?谢谢。
答案 0 :(得分:2)
当您使用grep
在空字符串中查找模式时,您将获得integer(0)
。使用grep
而不使用grepl
,如果字符串中找不到模式,则使用值logical
,无论字符串是否为空。
重现您的数据:
FALSE
解决您的问题:
d <- read.table(text='MATERIAL TEST_SEQ PARM1 PARM2 PARM3 PARM4 PARM5
Math 1 0001 0010 0100 NA 0000
Math 2 1100 1110 1111 1200 0200
Math 3 2211 NA 1022 2112 1202
Science 1 1112 0111 0110 0011 2001
Science 2 0122 2111 1222 0022 2010',
header=T, colClasses='character')
d[is.na(d)] <- ''
对于踢球,这是一种替代的矢量化方法来创建新列,然后可以listParms <- paste0('PARM', 1:5)
for(i in 1:length(listParms)) {
parm <- as.character(listParms[i])
lParm <- paste0(parm,"_LOG")
d[, lParm] <- apply(d, 1, function(x){
if(parm %in% names(d)) {
ifelse(grepl("0", x[parm], fixed=T), 0, NA)
} else {
NA
}
})
}
添加到原始cbind
:
data.frame
要扩展它以允许多个条件,您可以使用嵌套的listParmsSub <- listParms[listParms %in% names(d)]
ifelse(do.call(cbind,
setNames(lapply(d[, listParmsSub], function(x) {
grepl(0, x)
}), paste0(names(d[, listParmsSub]), '_LOG'))),
0, NA)
语句,例如:
ifelse