R:用第二个列表元素的值替换一个列表元素的值

时间:2019-02-03 14:52:06

标签: r list replace row

我想用列表的第二个元素的值替换列表中一个元素的值。具体来说,

  • 我有一个包含多个数据集的列表。
  • 每个数据集都有2个变量
  • 变量是因素
  • 每个数据集中第二个变量的第n个元素需要替换为每个数据集中第一个变量的第n个元素
  • 此外,替换后的值应称为“已替换”
  • dat1 <- data.frame(names1 =c("a", "b", "c", "f", "x"),values= c("val1_1", "val2_1", "val3_1", "val4_1", "val5_1"))
       dat1$values <- as.factor(dat1$values)
    dat2 <- data.frame(names1 =c("a", "b", "f2", "s5", "h"),values= c("val1_2", "val2_2", "val3_2", "val4_2", "val5_2"))
       dat2$values <- as.factor(dat2$values)
    list1 <- list(dat1, dat2)
    

    结果应该是相同的列表,但只是替换了第5个值。

    [[1]]
         names1  values
    1         a  val1_1
    2         b  val2_1
    3         c  val3_1
    4         f  val4_1
    5  replaced       x
    [[2]]
         names1  values
    1         a  val1_2
    2         b  val2_2
    3        f2  val3_2
    4        s5  val4_2
    5  replaced       h
    

    2 个答案:

    答案 0 :(得分:3)

    使用lapply的基本R方法,因为这两列都是因素,我们需要先添加新的levels,然后再用新值替换,否则这些值将变成NA

    n <- 5
    
    lapply(list1, function(x) {
       levels(x$values) <- c(levels(x$values), as.character(x$names1[n]))
       x$values[n] <- x$names1[n]
       levels(x$names1) <- c(levels(x$names1), "replaced")
       x$names1[n] <- "replaced"
       x
    })
    
    #[[1]]
    #    names1 values
    #1        a val1_1
    #2        b val2_1
    #3        c val3_1
    #4        f val4_1
    #5 replaced      x
    
    #[[2]]
    #    names1 values
    #1        a val1_2
    #2        b val2_2
    #3       f2 val3_2
    #4       s5 val4_2
    #5 replaced      h
    

    还有另一种方法,我们可以将两列都转换为字符,然后替换所需位置的值,然后再次将它们转换回因数,但是由于列表中的每个数据帧都可能很大,因此我们不想转换所有值转换为字符,然后返回到因数,仅更改一个值,这可能在计算上非常昂贵。

    答案 1 :(得分:3)

    这是tidyverse的一个选项。遍历listmapslice感兴趣的行(在这种情况下,它是最后一行,因此可以使用n()),{{1} }列值,并与原始数据绑定而没有最后一行

    mutate

    或者可以使用library(tidyverse) map(list1, ~ .x %>% slice(n()) %>% mutate(values = names1, names1 = 'replaced') %>% bind_rows(.x %>% slice(-n()), .)) #[[1]] # names1 values #1 a val1_1 #2 b val2_1 #3 c val3_1 #4 f val4_1 #5 replaced x #[[2]] # names1 values #1 a val1_2 #2 b val2_2 #3 f2 val3_2 #4 s5 val4_2 #5 replaced h 中的fct_c使它更紧凑。 forcats的不同级别可以与“值”和“名称1”列的factor组合在一起

    fct_c

    或者对library(forcats) map(list1, ~ .x %>% mutate(values = fct_c(values[-n()], names1[n()]), names1 = fct_c(names1[-n()], factor('replaced')))) 使用类似的方法,我们在base Rlist之间循环,然后将lapply转换为data.framematrix矩阵的子集,即用感兴趣的值删除的最后一行,并转换为rbind(默认为data.frame-因此它将转换为stringsAsFactors = TRUE

    factor