R:使用dplyr将列表重组为数据帧

时间:2015-03-25 20:18:12

标签: r list dataframe dplyr lapply

我会使用dplyr包的速度在整齐的dataFrame中转换结构化列表。 我想知道我现在发布的解决方案是“最先进的”还是有更快的东西。

这是我的首发列表示例:

l =list()
l[[1]] = list(member1=c(a=rnorm(1)),member2=matrix(rnorm(3),nrow=3,ncol=1,dimnames=list(c(letters[2:4]),c("sample"))))
l[[2]] = list(member1=c(a=rnorm(1)),member2=matrix(rnorm(3),nrow=3,ncol=1,dimnames=list(c(letters[2:4]),c("sample"))))
l[[3]] = list(member1=c(a=rnorm(1)),member2=matrix(rnorm(3),nrow=3,ncol=1,dimnames=list(c(letters[2:4]),c("sample"))))

有了这个结果(向你展示玩具结构):

l
[[1]]
[[1]]$member1
    a 
0.3340196 

[[1]]$member2
 sample
b 1.0098830
c 0.6413375
d 0.9080675

[[2]]
[[2]]$member1
    a 
0.0590878 

[[2]]$member2
  sample
b  0.5585736
c -0.5936157
d -0.3985687

[[3]]
[[3]]$member1
     a 
0.06242458 

[[3]]$member2
  sample
b -0.2873391
c  0.5326067
d -1.1635551

现在我将使用便利功能重新排列数据,以便在列表中导航:

organizeSamples = function(x){
  member = x$member2
  output = data.frame(key=rownames(member),value=member[,1])
  return(output)
}
l_new = lapply(l, organizeSamples)

现在dplyr做了魔术:

samples = dplyr::bind_rows(l_new)
samples

Source: local data frame [9 x 2]

  key      value
1   b  1.0098830
2   c  0.6413375
3   d  0.9080675
4   b  0.5585736
5   c -0.5936157 
6   d -0.3985687
7   b -0.2873391
8   c  0.5326067
9   d -1.1635551

有一种方法可以更快,更优雅地做到这一点使用dplyr压缩?

3 个答案:

答案 0 :(得分:3)

这是另一种方法,具有更多的dplyr / tidyr功能和管道,但是我没有在问题中测试其性能与原始方法,以及它是否更优雅取决于个人偏好。

library(dplyr); library(tidyr)

lapply(l, `[[`, 2) %>% 
    data.frame %>% 
    add_rownames("key") %>% 
    gather(x, value, -key) %>% 
    select(-x)

#      key      value
#1       b -1.1476570
#2       c -0.2894616
#3       d -0.2992151
#4       b  0.2522234
#5       c -0.8919211
#6       d  0.4356833
#7       b -0.2242679
#8       c  0.3773956
#9       d  0.1333364

答案 1 :(得分:1)

另一个纯粹的整体解决方案:

public abstract class A
{
    public static string MyMethod()
    {
        return "a";
    }
}

<强>更新 我以为你想要在member1和member2中组合信息,如果只需要member2,那就更简单了:

public class B<T> where T : A
{
    public void AnotherMethod()
    {
        var S1 = base.MyMethod();    // not allowed
        var S2 = T.MyMethod();       // not allowed
    }
}

答案 2 :(得分:0)

同样来自Hadleyverse,但不使用“dplyr”将考虑使用“reshape2”中的melt

library(reshape2)
melt(l)
#         value Var1   Var2      L2 L1
# 1  -0.6264538 <NA>   <NA> member1  1
# 2   0.1836433    b sample member2  1
# 3  -0.8356286    c sample member2  1
# 4   1.5952808    d sample member2  1
# 5   0.3295078 <NA>   <NA> member1  2
# 6  -0.8204684    b sample member2  2
# 7   0.4874291    c sample member2  2
# 8   0.7383247    d sample member2  2
# 9   0.5757814 <NA>   <NA> member1  3
# 10 -0.3053884    b sample member2  3
# 11  1.5117812    c sample member2  3
# 12  0.3898432    d sample member2  3

从那里,可以考虑使用“dplyr”进行一些清理。例如,要获得您描述的两列结果,您可以执行以下操作:

library(reshape2)
library(dplyr)

melt(l) %>%
  filter(L2 != "member1") %>%
  select(value, Var1)

(使用set.seed(1)创建的示例数据)。