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