【问题标题】:Using If to select dataframe by name from list in R使用 If 从 R 中的列表中按名称选择数据帧
【发布时间】:2018-08-02 21:16:27
【问题描述】:

在 R 中:我有一个包含 3 个数据框(Book1、Book2、Book3)的列表,列表名为 dflist4。我有一个代码要分别应用于列表中的每个数据帧,因为每个数据帧的 maxm 值都不同。我写了它,它有效,但只有当 Book1、Book2 和 Book3 都是相同大小的数据帧时。当它们的大小不相等时,代码将不会运行(错误:ops.dataframe == 仅针对大小相等的数据帧定义)。当我将 == 更改为 = 时,我知道这不合逻辑。无论数据框的大小如何,任何人都可以就如何根据名称从列表中选择数据框提出建议吗?

代码在这里:

eggplant<-function(x){
(if((x == (dflist4[["Book1"]])){
maxm = 3;
x %>% mutate(Col4 = (x[,3])/maxm);
})
(if((x == dflist4[["Book2"]])){
maxm = 2;
x %>% mutate(Col4 = (x[,3])/maxm);
})
(if((x == dflist4[["Book3"]])){
maxm = 1;
x %>% mutate(Col4 = (x[,3])/maxm);
})
}

test<-lapply(dflist4, eggplant)

【问题讨论】:

  • 请提供示例数据(发布您的实际数据的最小代表性片段,或生成代表性示例数据的代码)。对于Map/mapplypurrr::map2 来说,这听起来很快。
  • 您还将dplyr 与基本R 语法混合在一起:在mutate 中,您应该按名称(如Col4)而不是按索引(如x[, 3])引用列。
  • 谢谢!是 col3 是第三列。我现在正在阅读您的答案。为什么不能在 dplyr 中使用 R 基本语法?它有效...但不正确?
  • 以例如x %&gt;% mutate(Col4 = (x[,3])/maxm):不要在mutate里面使用x;管道和dplyr 语法的全部意义在于将转换连续应用于您调用一次的原始数据x。如果你必须这样做,你可以做x %&gt;% mutate(Col4 = (.[[3]])/maxm),但这很丑。

标签: r list dataframe dplyr


【解决方案1】:

根据我上面的 cmets,我假设 Book1Book2Book3 中的第三列称为 Col3

你可以使用purrr::map2

library(tidyverse)
purrr::map2(dflist4, c(3, 2, 1), function(df, maxm) df %>% mutate(Col4 = Col3 / maxm))

由于您不提供示例数据,这里是一个基于mtcars 的示例

purrr::map2(list(mtcars[1:3, ], mtcars[1:3, ]), c(10, 100), function(df, maxm)
    df %>% mutate(mpg.new = mpg / maxm))
#[[1]]
#   mpg cyl disp  hp drat    wt  qsec vs am gear carb mpg.new
#1 21.0   6  160 110 3.90 2.620 16.46  0  1    4    4    2.10
#2 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4    2.10
#3 22.8   4  108  93 3.85 2.320 18.61  1  1    4    1    2.28
#
#[[2]]
#   mpg cyl disp  hp drat    wt  qsec vs am gear carb mpg.new
#1 21.0   6  160 110 3.90 2.620 16.46  0  1    4    4   0.210
#2 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4   0.210
#3 22.8   4  108  93 3.85 2.320 18.61  1  1    4    1   0.228

【讨论】:

  • 谢谢!我假设 c(3,2,1) 会自动将 3 分配给列表中的第一个数据帧,将 2 分配给第二个,对吗?
  • 数据帧切换顺序怎么办?这将迫使它仅是它们在列表中的顺序,并且您每次都必须根据您希望它应用的顺序重写 c() ,不是吗?非常感谢您的解决方案
  • @MGru 是的,map2/mapply/Map 背后的整个概念是将函数应用于每个 list 参数的第一个元素,然后是第二个元素,然后是第三,以此类推。所以两个lists中元素的顺序需要匹配。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多