这是与my previous post相关的后续问题。下面是“我想做什么”的更具说明性的版本,而不是“我如何使这种方法有效”。
下面是生成“主”数据库的代码,我从中提取元素以便在其他函数中进一步使用。我经常根据组标识号的值提取数据元素。
##### generating data for example
set.seed(271828)
n.elements <- c(10,10,12,14,16,18)
group.number <- rep(1001:1006, n.elements)
element.id <- c(
seq(1,n.elements[1], 1),
seq(1,n.elements[2], 1),
seq(1,n.elements[3], 1),
seq(1,n.elements[4], 1),
seq(1,n.elements[5], 1),
seq(1,n.elements[6], 1) )
x1 <- round(rnorm(length(group.number),45, 12), digits=0)
x2 <- round(rbeta(length(group.number),2,4), digits = 2)
data.base <- as.data.frame(cbind(group.number, element.id, x1, x2))
data.base
##### data.base is representative of the large database
##### suppose I need to pull a set together made up of groups:
##### 1003, 1004, and 1001
groups.set.1 <- as.data.frame(c(1003, 1004, 1001))
bank.names <- c("group.number")
colnames(groups.set.1) <- bank.names
set.sort <- matrix(seq(1,nrow(groups.set.1),1))
sort.set.1 <- cbind(groups.set.1, set.sort)
set.1 <- as.data.frame(merge(sort.set.1, data.base,
by="group.number", all.x=TRUE))
##### this is how the dataset needs to be ordered for further use
set.1 <- set.1[order(set.1$set.sort, set.1$element.id ), ]
row.names(set.1) <- seq(nrow(set.1))
编辑:假设我想执行相同的任务来生成set.2
,其中set.2
由群组组成:1005,1006和1002.我可以只需复制上面的代码,并进行相关更改。但是,我想知道是否可以指定一个函数,以便我可以对它进行必要的更改,并让它根据需要生成输出数据帧。也许有一个名为group.extract
的函数,我可以在其中指定如下内容:
groups.2 <- c(1005, 1006, 1002)
group.extract(set.2, groups.2)
根据提供的评论,似乎列表是要走的路,并让函数调用列表,其中列表元素可以变化。
答案 0 :(得分:3)
我使用match
编写此函数,如下所示。在这里,我硬编码了输入数据框的列名,用于匹配和排序;这些也可以作为可选输入添加。输出的列顺序与您的略有不同,但也可以轻松更改。
getset <- function(g, d=data.base) {
d$set.sort <- match(d$group.number, g)
d <- d[!is.na(d$set.sort),]
d <- d[order(d$set.sort, d$element.id),]
rownames(d) <- NULL
d
}
你几乎完全按照你的建议使用它:
> set.1 <- getset(c(1003, 1004, 1001))
> head(set.1)
group.number element.id x1 x2 set.sort
1 1003 1 60 0.32 1
2 1003 2 28 0.18 1
3 1003 3 42 0.47 1
4 1003 4 43 0.08 1
5 1003 5 45 0.31 1
6 1003 6 27 0.48 1
虽然如果你有多个小组要把它们放在一个列表中并使用lapply
就可以了。
> groups <- list(group1=c(1003, 1004, 1001), group2=c(1005,1006,1002))
> sets <- lapply(groups, getset)
> lapply(sets, head)
$group1
group.number element.id x1 x2 set.sort
1 1003 1 60 0.32 1
2 1003 2 28 0.18 1
3 1003 3 42 0.47 1
4 1003 4 43 0.08 1
5 1003 5 45 0.31 1
6 1003 6 27 0.48 1
$group2
group.number element.id x1 x2 set.sort
1 1005 1 27 0.20 1
2 1005 2 51 0.48 1
3 1005 3 49 0.43 1
4 1005 4 48 0.20 1
5 1005 5 33 0.37 1
6 1005 6 41 0.50 1
答案 1 :(得分:2)
希望在SO中查看代码可以解决看似SAS后主义的中等严重情况。我认为这是一种更为R-ish的方式:
pick <- subset(data.base, group.number %in% c(1003, 1004, 1001) )
idx <- match(pick$group.number, c(1003, 1004, 1001) )
pick[ order(idx, pick$element.id), ]
#---------
group.number element.id x1 x2
21 1003 1 60 0.32
22 1003 2 28 0.18
23 1003 3 42 0.47
24 1003 4 43 0.08
25 1003 5 45 0.31
26 1003 6 27 0.48
snipped----
这就是将该策略纳入一个功能:
grp.ext.srt <- function(dfrm, grpid) { pick <- dfrm[ group.number %in% grpid , ]
idx <- match(pick$group.number, grpid ) ; rownames(pick) <- NULL
return(pick[ order(idx, pick$element.id), ])
}