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

Posted

技术标签:

【中文标题】R:用第二个列表元素的值替换一个列表元素的值【英文标题】:R: Replacing values of one list element with values of a second list element 【发布时间】:2019-06-27 11:31:23 【问题描述】:

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

我有一个包含多个数据集的列表。 每个数据集有 2 个变量 变量是因素 每个数据集第二个变量的第n个元素需要替换成每个数据集第一个变量的第n个元素 另外,被替换的值应该被称为“replaced”
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

【问题讨论】:

这是一个简化的例子。我有超过 4500 个数据集。 【参考方案1】:

这是tidyverse 的一个选项。循环遍历listmapslice感兴趣的行(在这种情况下,它是最后一行,所以n()可以使用),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

或者可以使用来自forcatsfct_c 使其更紧凑。不同的factor 级别可以与fct_c 组合在一起用于'values' 和'names1' 列

library(forcats)
map(list1, ~ .x %>% 
        mutate(values = fct_c(values[-n()], names1[n()]), 
               names1 = fct_c(names1[-n()], factor('replaced'))))

或使用与base R 类似的方法,其中我们使用lapply 循环遍历list,然后将data.frame 转换为matrixrbind 矩阵的子集,即用值删除的最后一行感兴趣,然后转换为data.frame(默认为stringsAsFactors = TRUE - 所以它会转换为factor

lapply(list1,  function(x)  as.data.frame(rbind(as.matrix(x)[-5, ], 
              c('replaced',  as.character(x$names1[5])))))

【讨论】:

你如何得到行号,Akrun?上面的答案中使用了 n @tobiassch 不,这里只有 5 行,n() 是最后一行。如果您有自定义 n,则在 slice(n) 中使用它 是的!我明白了,会试试的!【参考方案2】:

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

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

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

【讨论】:

以上是关于R:用第二个列表元素的值替换一个列表元素的值的主要内容,如果未能解决你的问题,请参考以下文章

tensorflow从列表中收集类似的值

touch事件中的touchestargetTouches和changedTouches详解

touch事件中的touchestargetTouches和changedTouches详解

替换方案列表中的值

touch事件中的touchestargetTouches和changedTouches详解

移动的 touch事件中的touchestargetTouches和changedTouches