我正在寻找将for
循环转换为lapply
或类似功能的帮助。
我有一个list
个相似的data.frame
,每个都包含
我想为每个数据帧反转b列中的值,但仅针对特定指标。例如,将“ b”中所有在a列中指标为2的值求反。
以下是一些示例数据:
x = data.frame(a = c(1, 2, 3, 2), b = (seq(from = .1, to = 1, by = .25)))
y = data.frame(a = c(1, 2, 3, 2), b = (seq(from = 1, to = .1, by = -.25)))
my_list <- list(x = , y = y)
my_list
$x
a b
1 1 0.10
2 2 0.35
3 3 0.60
4 2 0.85
$y
a b
1 1 1.00
2 2 0.75
3 3 0.50
4 2 0.25
我想要的输出如下:
my_list
$x
a b
1 1 0.10
2 2 0.65
3 3 0.60
4 2 0.15
$y
a b
1 1 1.00
2 2 0.25
3 3 0.50
4 2 0.75
我可以通过以下for循环实现所需的输出。
for(i in 1:length(my_list)){
my_list[[i]][my_list[[i]]['a'] == 2, 'b'] <-
1 - my_list[[i]][my_list[[i]]['a'] == 2, 'b']
}
但是。当我尝试将其滚动成类似lapply的形式时:
invertfun <- function(inputDF){
inputDF[inputDF['a'] == 2, 'b'] <- 1 - inputDF[inputDF['a'] == 2, 'b']
}
resultList <- lapply(X = my_list, FUN = invertfun)
我得到一个只有倒数值的列表:
resultList
$x
[1] 0.65 0.15
$y
[1] 0.25 0.75
我在这里想念什么?我试图应用(双关语意)来自以下方面的见解:
how to use lapply instead of a for loop, to perform a calculation on a list of dataframes in R
我将不胜感激任何见解或替代解决方案。我正在尝试将我的R技能提高到一个新的水平,apply
和类似的功能似乎是关键。
答案 0 :(得分:0)
我们可以使用lapply
遍历每个列表,并根据b
列中的值更改a
列。
my_list[] <- lapply(my_list, function(x) transform(x, b = ifelse(a==2, 1-b, b)))
my_list
#[[1]]
# a b
#1 1 0.10
#2 2 0.65
#3 3 0.60
#4 2 0.15
#[[2]]
# a b
#1 1 1.00
#2 2 0.25
#3 3 0.50
#4 2 0.75
使用map
中的purrr
可以完成同样的操作
library(purrr)
map(my_list, function(x) transform(x, b = ifelse(a==2, 1-b, b)))
答案 1 :(得分:0)
有关使用transform()
或map()
的相当优雅的解决方案,请参见上面的Ronak答案,但是对于那些追随我的脚步的人,如果我在自定义函数中添加一行到返回完整的数据帧,如下所示:
invertfun <- function(inputDF){
inputDF[inputDF['a'] == 2, 'b'] <- 1 - inputDF[inputDF['a'] == 2, 'b']
return(inputDF)
}
resultList <- lapply(X = my_list, FUN = invertfun)
更新-在进一步测试中,当一个数据帧中不存在所需的'a'值时,此解决方案将引发Error in x[[jj]][iseq] <- vjj : replacement has length zero
。因此最好不要走这条路,并使用上面接受的答案。
答案 2 :(得分:0)
lapply
通常不是迭代修改list
的最佳方法。 lapply
在任何情况下都会在内部生成一个循环,因此,如果您进行更明确的操作,通常更易于阅读:
for (i in seq_along(my_list)) {
my_list[[i]] <- within(my_list[[i]], {
b[a==2] <- 1 - b[a==2]
})}
如果在上面的示例中将within
替换为with
,我们将从您的初始解决方案lapply(X = my_list, FUN = invertfun)
中获得输出。
也就是说,不是用新的list
来替换list
元素,而是代替了vector