使用R将条件语句应用于数据框中的所有元素

时间:2014-01-19 21:24:42

标签: r if-statement dataframe conditional-statements

我的数据框看起来像这样 -

> dpd
         md       mean         sd       fsf        dii   n
2      77.5 0.02827206 0.05761423 0.8382353  29.648895 136
3     120.0 0.07058824 0.04696682 0.5882353   8.333333  17
NA       NA         NA         NA        NA         NA  NA
... ...
NA.8     NA         NA         NA        NA         NA  NA
13    650.0 0.00500000         NA 1.0000000 200.000000   1
NA.9     NA         NA         NA        NA         NA  NA
.. ...
NA.12    NA         NA         NA        NA         NA  NA
18    900.0 0.00500000         NA 1.0000000 200.000000   1

我想以这样一种方式制作一个if-else语句:只有当数据帧中所有'dii'值都是> = 20且'fsf'是> = 0.8时,该函数才会打印“GOOD” “,否则”你有问题!“。所以我试过这样的事情 -

if (dpd$fsf[!is.na(dpd$fsf)] > 0.8 & dpd$dii[!is.na(dpd$dii)] >= 20)
print("GOOD") else print("You have problem!")

数据框清楚地表明,第3行的值不遵守这两个条件,但R只考虑第一个元素,如下所示:

[1] "GOOD"
Warning message:
In if (dpd$fsf[!is.na(dpd$fsf)] > 0.8 & dpd$dii[!is.na(dpd$dii)] >=  :
  the condition has length > 1 and only the first element will be used

如何改进条件语句,使其显示“你有问题!”另外,有没有办法以我选择的颜色打印文本“GOOD”?

2 个答案:

答案 0 :(得分:1)

如果您想检查所有逻辑条件是否评估为TRUE,您应该将函数all包装在其周围。否则,您有一个逻辑向量,其中包含if内的多个元素,而if只会使用此向量的第一个元素。

x <- 1:3
y <- 1:3

x > 2 & y < 3
[1] FALSE FALSE FALSE

if (x < 2 & y < 3) print("good")
[1] "good"
Warning message:
In if (x < 2 & y < 3) print("good") :
  the condition has length > 1 and only the first element will be used

现在检查逻辑向量的所有元素是否为TRUE

all(x > 2 & y < 3)
[1] FALSE
if (all(x > 2 & y < 3)) print("good")

答案 1 :(得分:0)

由于fsfdii中的NA值,您的情况有点复杂。您需要在na.rm=T的调用中使用all(...)。将其用于dpd:

dpd
#      id    md       mean         sd       fsf        dii   n
# 1     2  77.5 0.02827206 0.05761423 0.8382353  29.648895 136
# 2     3 120.0 0.07058824 0.04696682 0.5882353   8.333333  17
# 3  <NA>    NA         NA         NA        NA         NA  NA
# 4  NA.8    NA         NA         NA        NA         NA  NA
# 5    13 650.0 0.00500000         NA 1.0000000 200.000000   1
# 6  NA.9    NA         NA         NA        NA         NA  NA
# 7 NA.12    NA         NA         NA        NA         NA  NA
# 8    18 900.0 0.00500000         NA 1.0000000 200.000000   1

with(dpd, if(all(fsf>=0.8 & dii>=20)) print("Good") else print("Problem")) 
# [1] "Problem"  

# remove the "bad" item (2nd row)
dpd.ok <- dpd[-2,]    # should print "Good"
# but it doesn't...
with(dpd.ok, if(all(fsf>=0.8 & dii>=20)) print("Good") else print("Problem"))
# Error in if (all(fsf >= 0.8 & dii >= 20)) print("Good") else print("Problem") : 
#   missing value where TRUE/FALSE needed

# setting na.rm=T fixes it
with(dpd.ok, if(all(fsf>=0.8 & dii>=20,na.rm=T)) print("Good") else print("Problem"))
# [1] "Good"