4

我有以下代码,

z <- data.frame(a=sample.int(10),b=sample.int(10),c=sample.int(10))
letter <- c("a","c","b") # this will be used as the argument to a function
vec <- unlist(lapply(1:length(letter), 
              function(x) cat(paste("z[[letter[",x,"]]],",sep=""))))
vec[length(vec)] <- paste("z[[letter[",length(vec),"]]]",sep="")

最后:

> vec    
[1] "z[[letter[1]]]," "z[[letter[2]]]," "z[[letter[3]]]" 

我想使用下面的代码vec来订购 dataframe 的行,z

z.sort <- z[with(z, order(???)),]

如何获取vec要评估的字符向量作为 的参数orderletter考虑到, 用于形成vec将是函数的参数,有没有更好的方法来做到这一点?

期望的输出是:

    a  b  c
5   1  1  9
10  2 10  2
1   3  7  1
9   4  2  5
8   5  8  6
2   6  4  3
4   7  9 10
3   8  3  8
6   9  5  7
7  10  6  4

或作为dput输出:

structure(list(a = 1:10, b = c(1L, 10L, 7L, 2L, 8L, 4L, 9L, 3L, 5L, 6L), c = c(9L, 2L, 1L, 5L, 6L, 3L, 10L, 8L, 7L, 4L)), .Names = c("a", "b", "c"), row.names = c(5L, 10L, 1L, 9L, 8L, 2L, 4L, 3L, 6L, 7L), class = "data.frame")
4

2 回答 2

4

这是您想要的(使用不同的随机数据):

> z[do.call(order, z[,letter]),]
    a  b  c
5   1  2  1
4   2  4  8
1   3  3  9
6   4  6  3
8   5  8  5
10  6  1  4
2   7  5  7
3   8 10  2
9   9  7  6
7  10  9 10

do.call让我们将一个列表作为参数发送给一个函数,因此我们可以重新排序 of 的列z并将它们发送给orderusing do.call,因为 adata.frame只是一种特殊的列表。

在函数中没有问题:

my.reorder <- function(dat, cols) { dat[do.call(order, dat[,cols]),] }
于 2012-04-19T16:53:15.207 回答
0

稍微澄清一下你的所作所为会有很大帮助,但有一些想法......

在您的sapply通话中,您可以通过以下方式大大简化:

vec <- sapply(letter, function(x) paste('z[["',x,'"]]',sep=''))

除非您尝试查看输出并对其进行分配,否则 cat 步骤是不必要的……但是最好使用使用print. 你可以通过使用得到你正在谈论的排序eval(parse(text=...))

z[order(eval(parse(text=vec[1])),]

并将每个排序作为一个列表:

lapply(vec, function(x) z[order(eval(parse(text=x))),])

但是...如果按字母中指定的每一列对 data.frame 进行排序是目标:

lapply(letter, function(x) z[order(z[[x]]),])

为您提供与上述所有繁琐步骤相同的输出。使用类似的东西eval(parse(text=...))经常意味着你在做一些愚蠢的事情,应该重新考虑你的步骤,因为很可能有一个更直接的解决方案。

于 2012-04-19T16:28:30.303 回答