0

我有一个data.frame这样的

df1<- read.table(text="  X1 X2 X3 X4 X5
            0  0 -1 0 0
            -1 0  0  -1  0
            0  0  0  0  0", header=TRUE)

和两个列表,就像这样

list1<- list()
list1[1]<-4
list1[2]<- list(c(2,5))
list1[3]<- 0

list2<- list()
list2[1]<- 3
list2[2]<- list(c(1,4))
list2[3]<- 0

我想要做的是使用 list1 从 df1 中选择列。然后必须根据使用 list2 选择的列的值来更改这些。

因此,例如:当 list1 的第一个元素被选中时,第一行的第 4 列将被选中。同时选取list2的第一个元素,提取第一行第三列的值。最后,df[1,4] 将被 df[1,3] 替换。

最终的data.frame如下

  X1  X2  X3  X4  X5
1  0   0  -1  -1   0
2 -1  -1   0  -1  -1
3  0   0   0   0   0

从一天开始,我一直在自己尝试,但即使在阅读了关于 SO 的类似问题后,我也无法弄清楚如何处理列表。

4

2 回答 2

3

鉴于您正在尝试分配,这似乎是 for 循环的一个非常简单的用例:

df2 <- df1
for(i in 1:length(list1)){
    if(!list1[[i]]==0 & !list2[[i]]==0) # deal with `0`'s
        df2[i,list1[[i]]] <- df1[i,list2[[i]]]
}
df2

这会给你这个:

> df2
  X1 X2 X3 X4 X5
1  0  0 -1 -1  0
2 -1 -1  0 -1 -1
3  0  0  0  0  0
于 2013-07-22T10:23:06.027 回答
1

一个疯狂的mapply解决方案可能只是强调有时for循环很好:

t(
  data.frame(
    mapply(
        function(l1,l2,sq) {
          if(all(l1==0) & all(l2==0)) 
            {df1[sq,]} else 
            {df1[sq,l1] <- df1[sq,l2]; df1[sq,]}
        },
        list1,
        list2,
        seq_along(list1)
      )
  )
)

结果:

   X1 X2 X3 X4 X5
X1 0  0  -1 -1 0 
X2 -1 -1 0  -1 -1
X3 0  0  0  0  0 
于 2013-07-22T11:33:07.243 回答