我是一名Coursera学生学习R.我意识到这个特定的问题已经被SO所涵盖;但是,我没有看到有人尝试使用dplyr包来解决问题。
期望的输出:
> complete("specdata", 332:1)[1:2,]
id nobs
313 332 301
312 331 353>
现在输出:
> complete("specdata", 332:1)[1:2,]
ID nobs
1 332 301
2 331 353
>
我的功能:
complete <- function(directory, id = 1:332) {
airpolutionfiles <- list.files("assignment1data/specdata", full.names=TRUE)
monitorsdata_all <- data.frame()
for (i in 1:332) {
monitorsdata_all <- rbind(monitorsdata_all, read.csv(airpolutionfiles[i]))
}
monitorsdata_all_subset <- subset(monitorsdata_all, complete.cases(monitorsdata_all) & ID %in% id)
countbyid <- count(monitorsdata_all_subset, "ID")
nobs <- rename(countbyid, c("freq"="nobs"))
arrange(nobs, desc(ID))
}
我已经在SO上看到了许多试图改变多个数据文件绑定/循环方式的解决方案。虽然我已经意识到,按照我的功能所写的方式,这是次优的,我要求你提供的任何帮助都不会搞砸,因为我仍然试图抓住在基础知识上。
所以我的问题归结为......在使用以下方式进行子集化之后
monitorsdata_all_subset <- subset(monitorsdata_all, complete.cases(monitorsdata_all) & ID %in% id)
无论如何,按组计算观察数(在本例中为id)并保留ID列与行#的相对位置?
答案 0 :(得分:3)
complete <- function(directory, id = 1:332) {
airpolutionfiles <- list.files(directory, full.names=TRUE)
nobs <- c()
for (i in 1:length(id)) {
monitorsdata_all <- read.csv(airpolutionfiles[id[i]])
nobs[i] <- sum(complete.cases(monitorsdata_all))
}
data.frame(id, nobs)
}
在您的原始代码中,您会做出一些选择,这会减慢您的进度。您没有使用directory
参数(我认为在编写示例时这是一个疏忽)。在将它们读入R之后,您还rbind
了所有文件。我不会这样做。特别是阅读您不会使用的文件。
for ( i in 1:332) {
这很慢。即使这个人有id=1
,你也会在每个文件中读到这个文件。为什么不直接读取用户选择的id文件。
接下来,我们计算完整的观察次数在循环中而不是在循环之外。这样我们就有了一个循环来收集观察而不是数据帧。
sum(complete.cases(monitorsdata_all))
该命令将计算完整观察的数量。在创建nobs
变量之后,很容易与用户选择的ID结合使用。
<强>奖金强>
您想了解如何按群组进行操作。我添加了四种方法来对R中的操作进行分组。甚至还有更多。
complete <- function(directory, id = 1:332) {
airpolutionfiles <- list.files(directory, full.names=TRUE)
monitorsdata_all <- data.frame()
for (i in id) {
monitorsdata_all <- rbind(monitorsdata_all, read.csv(airpolutionfiles[i]))
}
df <- subset(monitorsdata_all, complete.cases(monitorsdata_all))
#one way to count number of ids
nobs <- table(df$ID)
#a different approach. I use "sulfate" but I could have used any column (they all have the same length)
nobs <- tapply(df$sulfate, df$ID, length)
#Two more ways with aggregate. I add [,2] after bc it is a data frame and I want the second column
nobs <- aggregate(sulfate ~ ID, df, length)[,2]
nobs <- aggregate(df$sulfate, list(df$ID), length)[,2]
#then combine
data.frame(id, nobs)
}
答案 1 :(得分:1)
不。 Imma首先更改你的代码,这样我就能弄清楚你在问什么
library(dplyr)
data =
"assignment1data/specdata" %>%
list.files(full.names=TRUE) %>%
{ data_frame(file = .) } %>%
mutate(order_in_folder = 1:n() ) %>%
group_by(file, order_in_folder) %>%
do( read.csv(file) )
frequency =
data %>%
group_by(ID, order_in_folder) %>%
summarize(nobs = n() ) %>%
ungroup %>%
arrange(order_in_folder)