我想使用循环在某些文件上应用函数。我读了一个文件夹中的所有文件:
> tt <- list.files("/PATH.to.FILES/", full.names=TRUE)
> tt
[1] /PATH.to.FILES/AA.22.1
[2] /PATH.to.FILES/AA.22.10
[3] /PATH.to.FILES/AA.22.11
[4] /PATH.to.FILES/AA.22.12
[5] /PATH.to.FILES/AA.22.13
[6] /PATH.to.FILES/AA.22.2
[7] /PATH.to.FILES/AA.22.3
[8] /PATH.to.FILES/AA.22.4
[9] /PATH.to.FILES/AA.22.5
[10] /PATH.to.FILES/AA.22.6
[11] /PATH.to.FILES/AA.22.7
[12] /PATH.to.FILES/AA.22.8
[13] /PATH.to.FILES/AA.22.9
我想按照文件名中最后一个数字(即22
之后的数字)确定的顺序将其传递给循环。目前,如您所见,在1
之后,有10, 11, 12, 13
。我希望它是这样的:
> tt
[1] /PATH.to.FILES/AA.22.1
[2] /PATH.to.FILES/AA.22.2
[3] /PATH.to.FILES/AA.22.3
[4] /PATH.to.FILES/AA.22.4
[5] /PATH.to.FILES/AA.22.5
[6] /PATH.to.FILES/AA.22.6
[7] /PATH.to.FILES/AA.22.7
[8] /PATH.to.FILES/AA.22.8
[9] /PATH.to.FILES/AA.22.9
[10] /PATH.to.FILES/AA.22.10
[11] /PATH.to.FILES/AA.22.11
[12] /PATH.to.FILES/AA.22.12
[13] /PATH.to.FILES/AA.22.13
我尝试了mixedsort(tt)
,但它没有用。我很感激你的帮助。
答案 0 :(得分:2)
as.numeric
关于将所有内容分到最后一个小数点的结果:
> tt[ order( as.numeric( sub("^.+\\.", "", tt) ) ) ]
[1] "/PATH.to.FILES/AA.22.1 " "/PATH.to.FILES/AA.22.2 "
[3] "/PATH.to.FILES/AA.22.3 " "/PATH.to.FILES/AA.22.4 "
[5] "/PATH.to.FILES/AA.22.5 " "/PATH.to.FILES/AA.22.6 "
[7] "/PATH.to.FILES/AA.22.7 " "/PATH.to.FILES/AA.22.8 "
[9] "/PATH.to.FILES/AA.22.9" "/PATH.to.FILES/AA.22.10"
[11] "/PATH.to.FILES/AA.22.11" "/PATH.to.FILES/AA.22.12"
[13] "/PATH.to.FILES/AA.22.13"
如果你想匹配由点分隔的字符串中的倒数第二项,则会更复杂一些。我已经说明了一种匹配&#34;数字&#34;的可能方法。删除&#39; dot&#39;α结尾之前的字符。
sub("(^.+\\.)(\\d+)(\\.[A-Z]+$)", "\\2", "AA.BB.$i.2.CC")
[1] "2"
您需要查找?regex
。
答案 1 :(得分:1)
这是词典排序,这意味着语言基本上将变量视为字符串并逐字符比较(“200”大于“19999”,因为“2”大于'1')
要解决此问题,您可以
答案 2 :(得分:1)
这似乎与mixedsort
依赖gsub
将数字与字符串隔离开来的事实有关。不幸的是,.
是gsub
的一个特殊字符,他们用来隔离数字的匹配根本不喜欢它!
但是,如果你愿意用mixedsort
更喜欢的东西替换所有的点(比如*
,例如,这也应该是有风险的,因为它也是一个特殊的角色),它会工作:
x <- c("/PATH.to.FILES/AA.22.1", "/PATH.to.FILES/AA.22.10", "/PATH.to.FILES/AA.22.11",
"/PATH.to.FILES/AA.22.12", "/PATH.to.FILES/AA.22.13", "/PATH.to.FILES/AA.22.2",
"/PATH.to.FILES/AA.22.3", "/PATH.to.FILES/AA.22.4", "/PATH.to.FILES/AA.22.5",
"/PATH.to.FILES/AA.22.6", "/PATH.to.FILES/AA.22.7", "/PATH.to.FILES/AA.22.8",
"/PATH.to.FILES/AA.22.9")
x_star <- gsub("\\.", "*", x)
sorted_x_star <- gtools::mixedsort(x_star)
sorted_x <- gsub("\\*", ".", sorted_x_star)
答案 3 :(得分:0)
我确定这是一种更简单的方法,但这是我会立即采取的方法。
tt[order(sapply(strsplit(tt, ".", fixed = TRUE), function(x) as.numeric(x[5])))]
答案 4 :(得分:0)
这是一个应该有效的功能
#sample data
pp<-c("/PATH.to.FILES/AA.22.1", "/PATH.to.FILES/AA.22.10", "/PATH.to.FILES/AA.22.11",
"/PATH.to.FILES/AA.22.12", "/PATH.to.FILES/AA.22.13", "/PATH.to.FILES/AA.22.2",
"/PATH.to.FILES/AA.22.3", "/PATH.to.FILES/AA.22.4", "/PATH.to.FILES/AA.22.5",
"/PATH.to.FILES/AA.22.6", "/PATH.to.FILES/AA.22.7", "/PATH.to.FILES/AA.22.8",
"/PATH.to.FILES/AA.22.9")
这是我们的排序功能
multiorder <- function(x, seps="[./]") {
do.call(order,
read.table(text=sapply(strsplit(pp, seps),
paste, collapse="\t")))
}
测试出来
pp[multiorder(pp)]
# [1] "/PATH.to.FILES/AA.22.1" "/PATH.to.FILES/AA.22.2"
# [3] "/PATH.to.FILES/AA.22.3" "/PATH.to.FILES/AA.22.4"
# [5] "/PATH.to.FILES/AA.22.5" "/PATH.to.FILES/AA.22.6"
# [7] "/PATH.to.FILES/AA.22.7" "/PATH.to.FILES/AA.22.8"
# [9] "/PATH.to.FILES/AA.22.9" "/PATH.to.FILES/AA.22.10"
# [11] "/PATH.to.FILES/AA.22.11" "/PATH.to.FILES/AA.22.12"
# [13] "/PATH.to.FILES/AA.22.13"
我们的想法是,我们将/
和.
上的值拆分并处理每一列。我们通过read.table
发送它,以便每个&#34;列&#34;转换为正确的数字/字符data.type。然后我们根据所有列进行订购。只要要排序的部分都以某种方式分隔,这将适用于文件名的非常一般的情况。这确实假设所有记录具有相同数量的&#34;虚拟列&#34;。如果不是这种情况,您可能希望将它们共享列并根据它进行排序的部分进行子集化。