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
的一个选项。循环遍历list
和map
,slice
感兴趣的行(在这种情况下,它是最后一行,所以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
或者可以使用来自forcats
的fct_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
转换为matrix
、rbind
矩阵的子集,即用值删除的最后一行感兴趣,然后转换为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
的因子,然后再用新值替换它们,否则这些值将变为 NA
s。
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:用第二个列表元素的值替换一个列表元素的值的主要内容,如果未能解决你的问题,请参考以下文章
touch事件中的touchestargetTouches和changedTouches详解
touch事件中的touchestargetTouches和changedTouches详解