使用与表达式对应的字符向量作为函数的参数

时间:2012-04-19 16:07:33

标签: r dataframe

我有以下代码,

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使用以下代码对数据帧z的行进行排序,

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

如何将字符向量vec作为order的参数进行评估? 有没有更好的方法来记住,letter,用于形成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")

2 个答案:

答案 0 :(得分: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让我们将一个列表作为参数发送给函数,因此我们只需对z的列重新排序,然后使用order将其发送到do.calldata.frame只是一种特殊的列表。

在函数中没有问题:

my.reorder <- function(dat, cols) { dat[do.call(order, dat[,cols]),] }

答案 1 :(得分: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=...))的东西通常意味着你正在做一些愚蠢的事情,并且应该重新考虑你的步骤,因为很可能是一个更直接的解决方案。