![](/img/trans.png)
[英]How to use lapply to get the mean of a specific column in all dataframes of the list?
[英]How to use lapply to transform specific values in a list of dataframes
我正在寻找将for
循环转换为lapply
或类似函数的帮助。
我有一个类似data.frame
的list
,每个都包含
我想为每个数据框反转 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
我在这里缺少什么? 我试图应用(双关语)来自以下方面的见解:
如何使用 lapply 而不是 for 循环,对 R 中的数据帧列表执行计算
我很感激任何见解或替代解决方案。 我正在尝试将我的 R 技能提升到一个新的水平并apply
类似的功能似乎是关键。
我们可以使用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
使用来自purrr
map
也可以做到同样的事情
library(purrr)
map(my_list, function(x) transform(x, b = ifelse(a==2, 1-b, b)))
有关使用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)
更新 - 在进一步测试中,此解决方案Error in x[[jj]][iseq] <- vjj : replacement has length zero
引发Error in x[[jj]][iseq] <- vjj : replacement has length zero
当数据帧之一中不存在所需的“a”值时, Error in x[[jj]][iseq] <- vjj : replacement has length zero
。 所以最好不要走这条路并使用上面接受的答案。
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
,而是用新vector
替换list
元素。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.