繁体   English   中英

如何使用 lapply 转换数据框列表中的特定值

[英]How to use lapply to transform specific values in a list of dataframes

我正在寻找将for循环转换为lapply或类似函数的帮助。

我有一个类似data.framelist ,每个都包含

  • 指示符列 ('a')
  • 值列 ('b')

我想为每个数据框反转 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM