我已经看到一些问题,询问如何比较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中应该避免循环。有另一种方法可以实现吗?
我真的很感谢任何指点我正确方向的人,谢谢!
答案 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"
现在,请记住,您正在将数字与字符混合,因此这会强制您的矩阵与字符。