通过可变地复制列表元素来添加列:寻找优雅的解决方案

时间:2016-04-12 12:04:26

标签: r

我有一些数据被组织为每组每个受试者多次测量:

subject <- rep(c(1:6),each=4)
group <- c(rep("group1", 8),rep("group2",16))
measurement <- c("measure1","measure2")
trial <- rep(c(1:2),each=2)
df <- data.frame(subject,group,trial,measurement)

在另一个列表中,我有试验中管理的项目:

items <- list(c("A","B"),c("C","D"))

我想将这些项目添加到单独的列中,以便最终看起来像这样:

subject  group trial measurement item
      1 group1     1    measure1    A
      1 group1     1    measure2    A
      1 group1     2    measure1    B
      1 group1     2    measure2    B
      2 group1     1    measure1    A
      2 group1     1    measure2    A
      2 group1     2    measure1    B
      2 group1     2    measure2    B
      3 group2     1    measure1    C
      3 group2     1    measure2    C
      3 group2     2    measure1    D
      3 group2     2    measure2    D
      4 group2     1    measure1    C
      4 group2     1    measure2    C
...

所以基本上我想要items复制df$group中的向量,以便items[1]跨组1复制,items[2]跨组2复制(向量的每个元素)出现的次数与每个项目的测量值一样多。)

我正在寻找一般解决方案:群组数量,每组中的主题数量以及每个项目的测量数量都是可变的。但是,items中的向量始终具有相同的长度,并且每组的观察总数始终是项目数的倍数。

我更喜欢不使用for-loop的解决方案(我可以这样做,但我正在努力寻找更快更优雅的解决方案)。我觉得repseq_alonglapply的某种组合很容易解决这个问题,但我不确定如何将它们结合使用。

2 个答案:

答案 0 :(得分:3)

我们可以split&#39; df&#39;由&#39; group&#39;进入list,创建&#39;项目&#39;每个list元素中的列使用相应的&#39;项目&#39; list通过&#39;试用版Map传递给do.call(rbind, Map(function(x,y) transform(x, item= y[x$trial]), split(df, df$group), items)) 作为数字索引。

merge
转换&#39;项目后,

stack使用原始数据集。到一个&data; data.frame&#39; (使用merge(df, transform(setNames(stack(setNames(items, unique(df$group))), c("item", "group")), trial = 1:2)) )并创建&#39;试用版&#39;列。

constructor(@Inject(ElementRef) ele : ElementRef){}

答案 1 :(得分:1)

不确定这是否特别优雅,但它应该相当灵活,假设您的数据是常规的,如示例所示,它还使用lapplyrep

# get a count of each group, divide by the number of repetitions
# which is (item length * measurement count)
counts <- table(df$group) / length(items[[i]] * length(unique(df$measurement))
# print the vector
unlist(lapply(1:length(counts), 
         function(i) rep(items[[i]], counts[i], each=2)))
#  or add the vector to your data
df$item <- unlist(lapply(1:length(counts), 
                    function(i) rep(items[[i]], counts[i], each=2)))

这个答案得益于OP的输入,@ strangeloop。