我有2个文件:
eg
V1 V2 V3 V4 V5 V6 V7 V8 V9
1 0.066 0.71125 1.77 0.5045 0.7417104 1.584007 0.872757 1.729945 4
2 0.500 6.07500 20.30 1.7500 9.5017100 17.255490 11.180490 6.388851 4
3 0.670 0.67000 0.67 0.6700 0.0000000 0.670000 0.670000 0.000000 1
和
kl
I II III IV
1 0.80 0.60 0.40 0.20
2 0.75 0.55 0.35 0.15
3 65.60 50.70 38.80 24.00
我想比较来自“eg”的所有V2行与来自“kl”的所有充分行,'因为我需要(因此)评估哪一行得到哪一类(I,II,III,IV或下一栏中的其余部分为V)。 例如。
if eg[1,2] >= kl[1,1] --> I
if eg[1,2] >= kl[2,1] --> II
if eg[1,2] >= kl[3,1] --> III
if eg[1,2] >= kl[4,1] --> IV
else --> V
和例如[2,2]和[3,2]相同。
我修复了我的第一个循环和这样的迭代,但(当然)它不起作用......:
eg <- read.csv("eg.csv", header=F, sep=";")
eg <- eg[, -c(1,3,4,5,6,7,8,9)]
eg <- t(eg)
as.numeric(as.character(eg))
for (i in eg) {
if (is.na(eg[i,1]) || eg[i,1] == "NA") {
cat(("0"), sep=";")
} else if (eg[i,1] >= kl[i,1]) {
cat(("1"), sep=";")
} else if (eg[i,1] >= kl[i,2]) {
cat(("2"), sep=";")
} else if (eg[i,1] >= kl[i,3]) {
cat(("3"), sep=";")
} else if (eg[i,1] >= kl[i,4]) {
cat(("4"), sep=";")
} else {
cat(("5"), sep=";")
next}
}
R仅为两个第一行返回良好值,然后写入:
00Error in if (is.na(eg[i, 1]) || eg[i, 1] == "NA") { :
missing value where TRUE/FALSE needed
但是当我分别为每一行做同样的事情时 - 它起作用了。现在不:(
请帮帮我!谢谢你!
答案 0 :(得分:1)
这是一个更紧凑的方法:
c( "I", "II", "III", "IV") [ findInterval(eg[ , 1] , rev(kl[1, ] )) ]
这使用findInterval
函数来确定每个eg
值所在的类别(作为数字)。(findInterval
函数要求这些不递减,因此在此我们需要rev()
的问题 - 解析边界值。然后用它来选择一个字符向量。
如果你发布一个有意义的例子(而不是每行有不同数量的项目),我们可以演示如何进行循环或sapply
调用。
一步一步,R表示从最里面到最外层:
1)颠倒
中的中断kl
向量的顺序,以便它可以用作findInterval
2)运行
一起使用的索引eg[,1]
列到findInterval(.,.)
,返回一个与“[”3)从类别字符向量中提取适当的项目(基于eg [,1]值落入的中断间隔。
上面的代码是在没有合适的例子时发布的。通常需要在断点的任一侧放置-Inf
和Inf
,这样就不会从findInterval
获得零索引。这些代码似乎适用于现在提供的数据帧:
apply(kl,1,function(x) c( "V", "I", "II", "III", "IV") [
findInterval(eg[ , 1] , c( -Inf, rev(x ),Inf) ) ] )
1 2 3
[1,] "V" "V" "V"
[2,] "II" "II" "V"
[3,] "III" "III" "V"
由于apply
函数以列顺序返回行处理的方式,可能会想要转置它。
(我认为问题规范仍然搞砸了,因为它引用了3行对象的第4行(也有4列。数值仅在用作行时才有意义。)