将数据帧拆分为R中的列子集列表

时间:2017-06-24 00:11:34

标签: r list apply

我有一个如下数据框:

> set.seed(123)
> dat <- data.frame(samples = c("a.1","a.2","a.3","b.1","b.2","b.3"), ID = c(rep("A",3),rep("B",3))
> dat
  samples ID
1     a.1  A
2     a.2  A
3     a.3  A
4     b.1  B
5     b.2  B
6     b.3  B
> practice.data <- data.frame(a.1 = round(runif(5)), a.2=round(runif(5)),
  a.3=round(runif(5)),b.1=round(runif(5)),b.2=round(runif(5)),b.3=round(runif(5)))

> practice.data
  a.1 a.2 a.3 b.1 b.2 b.3
1   0   0   1   1   1   1
2   1   1   0   0   1   1
3   0   1   1   0   1   1
4   1   1   1   0   1   0
5   1   0   0   1   1   0

在上面的示例中,我想弄清楚如何将前三列放入最后三列的单独对象中(即在ID中由dat分隔)。将practice.data放入列表后,我计划使用lapply函数对每个列表对象的行求和,为每个ID返回一个向量。

我用for循环尝试了这个,但效率很低而且问题太多了,所以如果我能弄明白怎么做,似乎使用list和apply可能是最好的。

最终期望的输出将是这样的:

A    B
1    3
2    2
2    2
3    1
1    2

2 个答案:

答案 0 :(得分:2)

# map column names to the ID 
g <- dat$ID[match(names(practice.data), dat$samples)]
g

#[1] A A A B B B
#Levels: A B

# split the practice data into smaller data frames based on the map and call rowSums
as.data.frame(lapply(split.default(practice.data, g), rowSums))

#  A B
#1 1 3
#2 2 2
#3 2 2
#4 3 1
#5 1 2

答案 1 :(得分:0)

这是melt/dcast选项

library(data.table)
dcast(melt(setDT(practice.data, keep.rownames = TRUE), id.var = 'rn', 
  variable.name = 'samples')[, sum(value), .(rn, samples)
  ][dat, on = .(samples)], rn~ID, value.var = 'V1', sum)[, rn := NULL][]
#   A B
#1: 1 3
#2: 2 2
#3: 2 2
#4: 3 1
#5: 1 2