从R中的数据框列表中选择特定名称

时间:2014-11-26 12:00:54

标签: r

示例数据:

df <- data.frame(names=letters[1:10],name1=rnorm(10,1,1),name2=rexp(10,2))

list <- list(df,df)

vec_name <- c("f","i","c") # desired row names 

我想根据vec_name名称选择每个列表行:

期望的结果:

[[1]]
      names      value1    value2
   6   nd:f   -1.6323952 0.3117470
   9   nd:i    1.8270855 0.2475741
   3   nd:c    0.6978422 0.4695581   # the ordering does matter; must be as seen in vec_name

[[2]]
      names      value1    value2
   6   ad:f   -1.6323952 0.3117470
   9   ad:i    1.8270855 0.2475741
   3   ad:c    0.6978422 0.4695581

所需的输出2:在数据框中,我相信只是do.call(rbind,list)

然而应改为使用 vec_names 中的干净名称。

      names      value1    value2
   1      f   -1.6323952 0.3117470
   2      i    1.8270855 0.2475741
   3      c    0.6978422 0.4695581 
   4      f   -1.6323952 0.3117470
   5      i    1.8270855 0.2475741
   6      c    0.6978422 0.4695581

我试过sapply; lapply ...例如:

lapply(list, function(x) x[grepl(vec_name,x$names),])

编辑:请参阅上面的编辑问题。

2 个答案:

答案 0 :(得分:1)

你快到了。警告信息说:

Warning messages:
1: In grepl(vec_name, x$names) :
   argument 'pattern' has length > 1 and only the first element will be used

原因是您提供了vectorgrepl,期待regex(请参阅?regex)。你想要做的是match内容:

lapply(list, function(x) x[match(vec_name,x$names),])

这将为您提供listdata.frame个对象。如果你想在以后合并它们,只需使用:

do.call(rbind, lapply(list, function(x) x[match(vec_name,x$names),]))

或者您使用ldply中的library(plyr)

library(plyr)
ldply(list, function(x) x[match(vec_name,x$names),])
#   names       name1     name2
# 1     f  2.01421228 0.4489627
# 2     i  0.28899891 0.8323940
# 3     c -0.01746007 1.5309936
# 4     f  2.01421228 0.4489627
# 5     i  0.28899891 0.8323940
# 6     c -0.01746007 1.5309936

作为评论:避免为您的变量使用list这样的受保护名称,以避免不必要的影响。

<强>更新

考虑到评论(vec_namedata.frame中的名称完全不匹配),您应首先清除名称,然后执行match。然而,这是假设你未经清理过的&#39;名称包含已清除的名称,其前缀由冒号分隔(&#39;:&#39;)(如果不是这种情况,请调整regex语句中的gsub:< / p>

ldply(list, function(x) x[match(vec_name, gsub(".*:(.*)", "\\1", x$names)),])

答案 1 :(得分:1)

第一个输出

output1<-lapply(list,function(elt){
                       resmatch<-sapply(vec_name,function(x) regexpr(x,df$names))
                       elt<-elt[apply(resmatch,2,function(rg) which(rg>0)),]
                       colnames(elt)<-c("names","value1","value2")
                       return(elt)
                       })

>output1
[[1]]
  names     value1    value2
6  nd:f -0.2132962 0.7618105
9  nd:i -0.6580247 0.6010379
3  nd:c  0.9302625 0.1490061

[[2]]
  names     value1    value2
6  nd:f -0.2132962 0.7618105
9  nd:i -0.6580247 0.6010379
3  nd:c  0.9302625 0.1490061

对于第二个输出,您可以执行您想要的操作:

output2<-do.call(rbind,output1)

> output2

   names     value1    value2
6   nd:f -0.2132962 0.7618105
9   nd:i -0.6580247 0.6010379
3   nd:c  0.9302625 0.1490061
61  nd:f -0.2132962 0.7618105
91  nd:i -0.6580247 0.6010379
31  nd:c  0.9302625 0.1490061