问题设置:创建一个函数,将ID列选择的多个CSV文件合并为1个csv,然后按ID创建观察数量的输出。
预期:
complete("specdata", 30:25) ##notice descending order of IDs requested
## id nobs
## 1 30 932
## 2 29 711
## 3 28 475
## 4 27 338
## 5 26 586
## 6 25 463
我得到了:
> complete("specdata", 30:25)
id nobs
1 25 463
2 26 586
3 27 338
4 28 475
5 29 711
6 30 932
这是"错误"因为它已按ID排序。
我读取的CSV文件确实按降序排列数据。我的片段:
dfTable<-read.csv("~/progAssign1/specdata/tmpdata.csv")
ccTab<-complete.cases(dfTable)
xTab3<-as.data.frame(table(dfTable$ID[ccTab]),)
colnames(xTab3)<-c("id","nobs")
就我所知,第三行是排序发生的地方。我打破了表达式,它发生在table()调用中。我没有找到任何我可以传递的选项或参数来制作类似于= FALSE的东西。你想......
反正。任何帮助表示赞赏!
答案 0 :(得分:2)
因此,问题出在table
的输出中,默认排序。例如:
> r = sample(5,15,replace = T)
> r
[1] 1 4 1 1 3 5 3 2 1 4 2 4 2 4 4
> table(r)
r
1 2 3 4 5
4 3 2 5 1
如果你想采取第一次出现的顺序,你将通过重新编码table
函数来弄脏你的手:
unique_r = unique(r)
table_r = rbind(label=unique_r, count=sapply(unique_r,function(x)sum(r==x)))
table_r
[,1] [,2] [,3] [,4] [,5]
label 1 4 3 5 2
count 4 5 2 1 3
答案 1 :(得分:0)
您可以尝试这样的事情:
t1 <- c(5,3,1,3,5,5,5)
as.data.frame(table(t1)) ##result in ascending order
# t1 Freq
#1 1 1
#2 3 2
#3 5 4
t1 <- factor(t1)
as.data.frame(table(reorder(t1, rep(-1, length(t1)),sum)))
# Var1 Freq
#1 5 4
#2 3 2
#3 1 1
答案 2 :(得分:0)
解决此问题的一种方法是......不要使用table
。这是一个示例,我从您的数据创建三个单行数据集。然后我用read.table
的降序读取它们,似乎没问题。
这里真正重要的是,在读入R时,应将多个数据集放在列表中。您将获得您想要的数据集的确切顺序,以及其他好处。
一旦你按照你想要的方式将它们读入R,就可以更容易地在最后订购它们。排序(对我而言)通常是最后一步。
> dat <- read.table(h=T, text = "id nobs
1 25 463
2 26 586
3 27 338
4 28 475
5 29 711
6 30 932")
写三个单行文件:
> write.table(dat[3,], "dat3.csv", row.names = FALSE)
> write.table(dat[2,], "dat2.csv", row.names = FALSE)
> write.table(dat[1,], "dat1.csv", row.names = FALSE)
使用3:1
订单阅读:
> do.call(rbind, lapply(3:1, function(x){
read.table(paste0("dat", x, ".csv"), header = TRUE)
}))
# id nobs
# 1 27 338
# 2 26 586
# 3 25 463
然后,如果我们将3:1
更改为1:3
,则行符合我们的要求
> do.call(rbind, lapply(1:3, function(x){
read.table(paste0("dat", x, ".csv"), header = TRUE)
}))
# id nobs
# 1 25 463
# 2 26 586
# 3 27 338
仅适用于fun
> fun <- function(z){
do.call(rbind, lapply(z, function(x){
read.table(paste0("dat", x, ".csv"), header = TRUE) }))
}
> fun(c(2, 3, 1))
# id nobs
# 1 26 586
# 2 27 338
# 3 25 463
答案 3 :(得分:0)
在您的情况下,您正在抱怨table
函数的操作,其中一个参数返回名称按升序排列的项目,并按降序排列它们。您可以简单地在table
调用周围使用rev()函数。
xTab3<-as.data.frame( rev( table( dfTable$ID[ccTab] ) ),)
(我不确定最后一个逗号在那里做了什么。)原始中的排序顺序不会决定表操作的顺序。通常,R将返回带有以alpha(升序)顺序排序的离散标签的结果,除非已经以不同方式指定了因子项的级别。这是那些可能难以直观的特定于R的规则之一。可能难以理解的另一个特定于R的规则(虽然这里不是真正的问题)是通常期望参数以R列表的形式存在。
此时考虑R表对象可能是明智的(以及as.data.frame
调用会发生什么。table
- 对象实际上是R-matrices,因此您要排序的功能by实际上是该表对象的rownames并且是类字符:
r = sample(5,15,replace = T)
table(r)
#r
#2 3 4 5
#5 3 2 5
rownames(table(r))
#[1] "2" "3" "4" "5"
str(as.data.frame(table(r)))
#-------
'data.frame': 4 obs. of 2 variables:
$ r : Factor w/ 4 levels "2","3","4","5": 1 2 3 4
$ Freq: int 5 3 2 5
答案 4 :(得分:0)
我只是想分享我已完成的这项功课
complete <- function(directory, id=1:332){
setwd("E:/Coursera")
files <- dir(directory, full.names = TRUE)
data <- lapply(files, read.csv)
specdata <- do.call(rbind, data)
cleandata <- specdata[!is.na(specdata$sulfate) & !is.na(specdata$nitrate),]
targetdata <- data.frame(Date=numeric(0), sulfate=numeric(0), nitrate=numeric(0), ID=numeric(0))
result<-data.frame(id=numeric(0), nobs=numeric(0))
for(i in id){
targetdata <- cleandata[cleandata$ID == i, ]
result <- rbind(result, data.frame(table(targetdata$ID)))
}
names(result) <- c("id","nobs")
result
}