R中的多个列有条件地修改其他列(不创建新列)

时间:2014-09-30 21:58:57

标签: r

我已经看到一些问题,询问如何比较R中两列之间的值,但我无法弄清楚如何使用两列来有条件地编辑行的其余部分。我基本上试图为每一行应用不同的范围。

例如:

data <- matrix(c(0.1, 0.3, 0.1,0.5,0.4,0.2,0.3,2,2,1,0.1,0.5,0.4,0.3,0.2), nrow=3, ncol=5)
colnames(data) <- c("Min", "Lim", "Var1", "Var2", "Var3")
data
     Min    Lim    Var1    Var2    Var3
[1,] 0.1    0.5     0.3     1.0     0.4
[2,] 0.3    0.4     2.0     0.1     0.3
[3,] 0.1    0.2     2.0     0.5     0.2

我想将Var1,Var2和Var3与Min和Lim列进行比较。如果第1行中的Var1,Var2或Var3值低于第1行中的最小值,则该值应替换为“最小值以下”。如果某个值高于Min但低于Lim,则该值应替换为“Below Lim”。如果值高于Min和Lim,则它应保持原样。 我的预期输出是:

data
     Min    Lim    Var1       Var2       Var3
[1,] 0.1    0.5  Below Lim     1.0     Below Lim
[2,] 0.3    0.4     2.0     Below Min  Below Lim
[3,] 0.1    0.2     2.0        0.5        0.2   

我是R的新手,并尝试使用像...这样的行循环遍历

for(i in 1:nrow(data){
    data[i,3:5] <- ifelse(data[,3:5] > data[,1], data[,3:5], "Below LOD")
}

...但这显然不适用于多列(Var1,Var2,Var3),我知道在R中应该避免循环。有另一种方法可以实现吗?

我真的很感谢任何指点我正确方向的人,谢谢!

2 个答案:

答案 0 :(得分:4)

library(data.table)
DT <- data.table(data)

## The columns need to be converted to strings. You cannot mix strings with numbers
varCols <- grep("^Var", names(DT), value=TRUE, ignore.case=TRUE)
DT[, (varCols) := lapply(.SD, as.character), .SDcols = varCols]

DT[Var1 < Lim, Var1 := ifelse(Var1 < Min, "Below Min", "Below Lim")]
DT[Var2 < Lim, Var2 := ifelse(Var2 < Min, "Below Min", "Below Lim")]
DT[Var3 < Lim, Var3 := ifelse(Var3 < Min, "Below Min", "Below Lim")]

DT
#    Min Lim      Var1      Var2      Var3
# 1: 0.1 0.5 Below Lim         1 Below Lim
# 2: 0.3 0.4         2 Below Min Below Lim
# 3: 0.1 0.2         2       0.5       0.2

您可以以编程方式执行重复行:

for (col in varCols)
  DT[get(col) < Lim, (col) := ifelse((get(col)) < Min, "Below Min", "Below Lim")]

答案 1 :(得分:0)

尝试:

data[,c("Var1", "Var2", "Var3")] <- 
  ifelse(data[,c("Var1", "Var2", "Var3")] < data[,"Min"], "Below Min",
              ifelse(data[,c("Var1", "Var2", "Var3")] < data[,"Lim"], "Below Lim", data))    

这会给你:

data
    Min   Lim   Var1        Var2        Var3       
[1,] "0.1" "0.5" "Below Lim" "1"         "Below Lim"
[2,] "0.3" "0.4" "2"         "Below Min" "Below Lim"
[3,] "0.1" "0.2" "2"         "0.5"       "0.2"    

现在,请记住,您正在将数字与字符混合,因此这会强制您的矩阵与字符。