替换数据框列表中的列值

时间:2017-09-02 01:02:26

标签: r list for-loop lapply tidyverse

我有以下数据框示例列表:

cat <- rnorm(5)
dog <- rnorm(5)
mouse <- rnorm(5)

df1 <- cbind(cat,dog,mouse)
df2 <- cbind(cat,dog,mouse)
df3 <- cbind(cat,dog,mouse)

list.1 <- list(df1 = df1,df2 = df2,df3 = df3)
list.1

$df1
            cat        dog      mouse
[1,] -0.6991598 -0.8630006 -0.7564806
[2,]  0.7645475  1.3571995  0.8939621
[3,]  1.0608070 -0.8455111  0.5198387
[4,] -0.2008916 -0.7971714  0.8477894
[5,] -0.6988800  1.0717351 -1.3684944

$df2
            cat        dog      mouse
[1,] -0.6991598 -0.8630006 -0.7564806
[2,]  0.7645475  1.3571995  0.8939621
[3,]  1.0608070 -0.8455111  0.5198387
[4,] -0.2008916 -0.7971714  0.8477894
[5,] -0.6988800  1.0717351 -1.3684944

$df3
            cat        dog      mouse
[1,] -0.6991598 -0.8630006 -0.7564806
[2,]  0.7645475  1.3571995  0.8939621
[3,]  1.0608070 -0.8455111  0.5198387
[4,] -0.2008916 -0.7971714  0.8477894
[5,] -0.6988800  1.0717351 -1.3684944

我想将每个数据框中的dog列替换为另一个数据框中的相应列。

使用变量“dog”的新值创建数据框

new.dog1 <- c(1,1,2,2,3)
new.dog2 <- c(10,10,20,20,30)
new.dog3 <- c(100,100,200,200,300)
new.dogs <- cbind(new.dog1, new.dog2, new.dog3)
new.dogs

     new.dog1 new.dog2 new.dog3
[1,]        1       10      100
[2,]        1       10      100
[3,]        2       20      200
[4,]        2       20      200
[5,]        3       30      300

我正在尝试做的伪代码(不起作用):

updated.list <- for(i in list.1) {
  list.1[[i]][,2] <- new.dogs[,i]
  return(list.1)
  }

输出应该是什么样的:

> updated.list
$df1
            cat dog      mouse
[1,] -0.6991598   1 -0.7564806
[2,]  0.7645475   1  0.8939621
[3,]  1.0608070   2  0.5198387
[4,] -0.2008916   2  0.8477894
[5,] -0.6988800   3 -1.3684944

$df2
            cat dog      mouse
[1,] -0.6991598  10 -0.7564806
[2,]  0.7645475  10  0.8939621
[3,]  1.0608070  20  0.5198387
[4,] -0.2008916  20  0.8477894
[5,] -0.6988800  30 -1.3684944

$df3
            cat dog      mouse
[1,] -0.6991598 100 -0.7564806
[2,]  0.7645475 100  0.8939621
[3,]  1.0608070 200  0.5198387
[4,] -0.2008916 200  0.8477894
[5,] -0.6988800 300 -1.3684944

在我的for循环中,我认为问题在于new.dogs[,i]位代码?理想情况下,如果可能,我宁愿使用lapplytidyverse解决方案而不是for循环...

2 个答案:

答案 0 :(得分:4)

基地R:

updated.list <- mapply(function(old, new, which) {
  old[,which] <- new
  old
}, list.1, data.frame(new.dogs), "dog", SIMPLIFY = FALSE)

答案 1 :(得分:1)

如果您想使用tidyverse,您可以保留new.dogs列表并清理留下的矩阵混乱cbind(),然后使用map2()成对迭代两个列表如下:

library(tidyverse)

# use new.dogs as a list instead
new.dogs <- list(new.dog1, new.dog2, new.dog3)

# cbind() creates matrixes from vectors, not tidy tibbles/dataframes
list.1 <- map(list.1, as.tibble) 

# iterate and replace pairwise (list.1[[i]] <- .; new.dogs[[i]] <- .y)
map2(list.1, new.dogs, ~ mutate(., dog = .y))