如何使用 for 循环在数据帧的行内遍历。
我正在编写代码来查找颜色为"E"的钻石的频率。但相反,我正在获取所有行的频率计数。以下是代码片段:
dataframe1 <- data.frame(diamonds)
cntx <- function() {
cnt <- 0
for(i in 1:nrow(dataframe1)) {
if(dataframe1$color == "E") cnt <- cnt+1
}
return(cnt)
}
我从您的代码中收到以下警告:
Warning messages:
1: In if (dataframe1$color == "E") { :
the condition has length > 1 and only the first element will be used
问题是数据帧 1$color 是数据帧 1 行数长度的向量。您正在比较长度为 x 的向量与长度为 1 的"向量"("E")。因此,R 仅使用比较产生的布尔向量的第一个元素。第一个元素似乎是"True"。由于语句始终为"True",因此它只是计算每一行。
以下情况如何?
dataframe1 <- data.frame(color = c("E", "F", "E", "F"))
sum(dataframe1$color == "E")
在这种情况下不需要循环。这里有一些方法可以做到这一点:
基数 R:
table(diamonds$color)
哈德利宇宙
library(tidyverse)
diamonds %>%
count(color)
如果你坚持循环:
cntx <- function(c){
cnt <- 0
for (i in 1:nrow(c)) {
if (c$color[i] == "E") cnt <- cnt+1 #you forgot the i
}
return (cnt)
}
cntx(diamonds)
您忘记了循环中的 [i],因此每次计算整个布尔向量c$color == "E"
并且只有第一个元素(即 T)用于求值时,因此出现警告:
1: In if (c$color == "E") cnt <- cnt + 1 :
the condition has length > 1 and only the first element will be used
结果相当于i
数。
正如其他人所提到的,有许多工具可以用更少的击键来解决这个问题。
我个人更喜欢data.table
解决方案:
library(data.table)
x <- as.data.table(diamonds)
x[color == "E",.N]
返回以下内容
[1] 9797
更复杂的查询几乎不需要任何额外的击键。
x[,.(Count = .N), by = .(color)]
返回
color count
E 9797
I 5422
J 2808
H 8304
F 9542
G 11292
D 6775
或
x[price > 10000,.(carat = mean(carat)), by = .(color)]
返回
color carat
J 2.146045
E 1.523220
G 1.638468
F 1.538835
I 1.980648
D 1.463780
H 1.866069