1

我有一个 6 列的 data.frame。第一个用于主题,第二个用于实验中的块,第 3,4 和 5 列是我需要计算二进制分数(0 或 1)的值,我想将其添加到第六列(这就是为什么现在,它充满了0)。

head(kfdblock3to9)
    subject time        gr       ugr      sdugr IL
40002.3   40002    3 0.4475618 0.3706000 0.02994533  0
40002.4   40002    4 0.4361786 0.3901111 0.01846110  0
40002.5   40002    5 0.4279880 0.4550000 0.02811839  0
40002.6   40002    6 0.4313647 0.4134444 0.04352974  0
40002.7   40002    7 0.4420889 0.4394286 0.02883143  0
40002.8   40002    8 0.4325227 0.3960000 0.06559222  0

我正在尝试使用 for 循环来做到这一点,但我是 R 的初学者,我在这方面遇到了困难。我试图实现的评分公式是:如果第 3 列中的值 ($gr) 小于第 4 列中的值 ($ugr) 和第 5 列中的值 ($sdugr) 之间的差值的 0.35 倍),则主体收到 1,否则为 0。

到目前为止我尝试过的是:

for (i in kfdblock3to9$subject) {
     if (kfdblock3to9$gr<(kfdblock3to9$ugr-(.35*kfdblock3to9$sdugr))) 
                 kfdblock3to9$IL=1
         else kfdblock3to9$IL=0
    }

这给了我 50 个警告,都说:“条件的长度 > 1,并且只使用第一个元素”

我想我当时对索引做错了,但我无法弄清楚。任何帮助深表感谢。

4

4 回答 4

2

看看withinifelse

kfdblock3to9 <- 
within(kfdblock3to9,
  IL <- ifelse( gr < ugr - 0.35 * dugr, 1, 0)
)

within()不是真的那么必要,但它使您的代码更易读和更容易理解。

为什么会出错?那是因为你的条件是矢量化的:试试

kfdblock3to9$gr<(kfdblock3to9$ugr-(.35*kfdblock3to9$sdugr))

你会看到它返回一个逻辑向量。现在一个if()子句一次只能处理一个布尔值。如果你有一个矢量化的结果,你需要一个矢量化的解决方案,那就是ifelse()

于 2012-05-22T11:54:55.640 回答
2

为了解决你的问题,我会建议这样的事情:

kfdblock3to9[, "IL"] <- ifelse(kfdblock3to9$gr < (kfdblock3to9$ugr-(0.35*kfdblock3to9$sdugr)), 1, 0);

(矢量化方法通常比循环快。)

你的循环是错误的,因为你不尊重你的 index i。您必须使用i来访问循环中的行:

for (i in seq(along=kfdblock3to9)) {
    cat("row:", i, kfdblock3to9[i, "subject"], "\n");
}
于 2012-05-22T11:54:59.437 回答
2

你想要的是一个逻辑测试。因此,您可以避免使用loop, 甚至ifelse, 并且只需执行以下操作:

kfdblock3to9$IL <- with(kfdblock3to9, gr < (ugr-0.35*sdugr))

IL 列将包含 TRUE 或 FALSE,而不是 1 或 0。如果您更喜欢使用整数,可以执行以下操作:

kfdblock3to9$IL <- as.integer(with(kfdblock3to9, gr < (ugr-0.35*sdugr)))
于 2012-05-22T11:58:16.607 回答
0

在这种情况下,您不应该使用循环。以后无论何时使用循环,都需要使用索引:

for (i in 1:length(kfdblock3to9$subject)) {
     if (kfdblock3to9[i,"gr"] < (kfdblock3to9[i, "ugr"] - .35 * kfdblock3to9[i, "sdugr"])) 
                 kfdblock3to9[i,"IL"]=1
     else  kfdblock3to9[i,"IL"]=0
}


kfdblock3to9
     subject time        gr       ugr      sdugr IL
40002.3   40002    3 0.4475618 0.3706000 0.02994533  0
40002.4   40002    4 0.4361786 0.3901111 0.01846110  0
40002.5   40002    5 0.4279880 0.4550000 0.02811839  1
40002.6   40002    6 0.4313647 0.4134444 0.04352974  0
40002.7   40002    7 0.4420889 0.4394286 0.02883143  0
40002.8   40002    8 0.4325227 0.3960000 0.06559222  0
于 2012-05-22T11:54:57.080 回答