我想用列表的第二个元素的值替换列表中一个元素的值。具体来说,
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
答案 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
的一个选项。遍历list
与map
,slice
感兴趣的行(在这种情况下,它是最后一行,因此可以使用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 R
和list
之间循环,然后将lapply
转换为data.frame
,matrix
矩阵的子集,即用感兴趣的值删除的最后一行,并转换为rbind
(默认为data.frame
-因此它将转换为stringsAsFactors = TRUE
)
factor