在R中有没有办法停止排序表

时间:2014-07-19 15:51:39

标签: r sorting csv

问题设置:创建一个函数,将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的东西。你想......

反正。任何帮助表示赞赏!

5 个答案:

答案 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
}