如何使用子集和逻辑语句循环 R 中的值?

How to loop through values in R using subsets and logical statements?

我正在尝试通过 ID 值和特定条件(如下指定)关联数据集 (a) 中的硫酸盐和硝酸盐值。数据集包含三列(ID、硫酸盐、硝酸盐)。当我单独 运行 每个 ID 值时代码有效,但现在我试图通过所有 ID 值设置一个循环到 运行,然后按 ID 值将所有相关性打印到单个向量中.循环没有打印出相关值,因为我确定我没有正确保存它们。如何修改下面的代码以根据每个 ID 值打印出相关值向量?

for (i in 1:5) {
    if (a$ID==i && length(a$ID==i) > 10) {
        cor(a$sulfate[a$ID==i], a$nitrate[a$ID==i])
    }
}

试试看:

res <- c()
for(i in 1:5) {
  res[i] <- cor(a$sulfate[a$ID==i], a$nitrate[a$ID==i])
}
res

说明

#Example data frame
df <- data.frame(ID = c(1, 1, 2, 2), sulfate = c(4, 3, 5, 1), nitrate = c(10,8, 2, 4), stringsAsFactors=F)
df
  ID sulfate nitrate
1  1       4      10
2  1       3       8
3  2       5       2
4  2       1       4

我们尝试进行逻辑测试。 Return 如果 ID 等于 1:

'yes' 的输出
if(a$ID==1) 'yes'
[1] "yes"
Warning message:
In if (a$ID == 1) "yes" :
  the condition has length > 1 and only the first element will be used

我们得到了'yes'的结果,但是我们也得到了一个警告。因为:

a$ID==1
[1]  TRUE  TRUE FALSE FALSE

测试检查 a$ID 的每个元素是否等于 1。这是 if 语句的问题。 R 如何知道要使用哪个 TRUEFALSE 值进行测试?所以它只使用第一个。

在您的代码中,您正在像 if 语句中那样传递向量。您希望 if 语句 return TRUEFALSE 的一个值。或者一起避免。

向量化

随着您变得更高级,您可以通过矢量化函数调用来避免此循环。

sapply(split(a, a$ID), function(x) cor(x['sulfate'], x['nitrate']))
 1  2 
 1 -1 

一些 R 用户编写了很棒的包来处理这些类型的问题。您将需要 dplyrdata.table。这里有两个快速的选择。

library(dplyr)
a %>%
  group_by(ID) %>%
  summarize(Cor =cor(sulfate, nitrate))
Source: local data table [2 x 2]

  ID Cor
1  1   1
2  2  -1

library(data.table)
setDT(a)[, .(cor(sulfate, nitrate)), ID]
   ID V1
1:  1  1
2:  2 -1