[英]Using a vector of characters that correspond to an expression as an argument to a function
我有以下代碼,
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
參數進行評估? 是否有更好的方法來記住,用於形成vec
letter
將是函數的參數?
期望的輸出將是:
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")
這是你想要的(使用不同的隨機數據):
> 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
的列並使用do.call
將它們發送到order
,因為data.frame
只是一種特殊的列表。
在函數中沒有問題:
my.reorder <- function(dat, cols) { dat[do.call(order, dat[,cols]),] }
稍微澄清一下你的行為會有多大幫助,但有些想法......
在您的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=...))
東西通常意味着你正在做一些愚蠢的事情並且應該重新考慮你的步驟,因為很可能是一個更直接的解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.