Как создать функцию для подмножества данных, где переданные ей аргументы различаются - PullRequest
1 голос
/ 23 марта 2012

Это дополнительный вопрос, связанный с моим предыдущим постом .Ниже приведена более объяснительная версия «что я хочу сделать», а не «как заставить этот метод работать».

Ниже приведен код, который создает «основную» базу данных, из которой я извлекаю элементы для дальнейшего использования в других функциях.Я регулярно извлекаю элементы данных, основываясь на значении идентификационного номера группы.

  • Цель: я хотел бы иметь возможность "обернуть" спецификации, которые меняются (например, имя выходного кадра данных и выбранные группы), в функцию, которую можно вызывать.

#####  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)

На основании предоставленных комментариев кажется, что список - это путь, и функция должна вызыватьсписок, где элементы списка могут различаться.

Ответы [ 2 ]

3 голосов
/ 23 марта 2012

Я бы написал эту функцию, используя 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
2 голосов
/ 23 марта 2012

Надеюсь, что пересмотр кода в SO может помочь в лечении, как представляется, умеренно тяжелого случая пост-SAS-изма. Я думаю, что это более R-иш способ сделать это:

 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), ])
      }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...