如何使用子集和逻辑语句循环 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 如何知道要使用哪个 TRUE
或 FALSE
值进行测试?所以它只使用第一个。
在您的代码中,您正在像 if 语句中那样传递向量。您希望 if 语句 return TRUE
或 FALSE
的一个值。或者一起避免。
向量化
随着您变得更高级,您可以通过矢量化函数调用来避免此循环。
sapply(split(a, a$ID), function(x) cor(x['sulfate'], x['nitrate']))
1 2
1 -1
一些 R 用户编写了很棒的包来处理这些类型的问题。您将需要 dplyr
和 data.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
我正在尝试通过 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 如何知道要使用哪个 TRUE
或 FALSE
值进行测试?所以它只使用第一个。
在您的代码中,您正在像 if 语句中那样传递向量。您希望 if 语句 return TRUE
或 FALSE
的一个值。或者一起避免。
向量化
随着您变得更高级,您可以通过矢量化函数调用来避免此循环。
sapply(split(a, a$ID), function(x) cor(x['sulfate'], x['nitrate']))
1 2
1 -1
一些 R 用户编写了很棒的包来处理这些类型的问题。您将需要 dplyr
和 data.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