[英]How to apply a function to specific dataframes within a list
我有几个数据框,每个都包含温度数据,我将它们放入一个列表中(如下所示是一些模拟数据):
df1 <- data.frame(XH_warmed_air_1m = c(60, 70, 80, 90, 100),
XH_ambient_air_1m = c(60, 70, 80, 90, 100))
df2 <- data.frame(XH_warmed_air_1m = c(60, 70, 80, 90, 100),
XH_ambient_air_1m = c(60, 70, 80, 90, 100))
df3 <- data.frame(XH_warmed_air_1m = c(0, 10, 20, 30, 40),
XH_ambient_air_1m = c(0, 10, 20, 30, 40))
list <- list(df1=df1, df2=df2, df3=df3)
此列表中的df1和df2包含华氏温度数据,需要转换为摄氏度(df3的数据已经是摄氏度)。 所以,我做了一个 function 来自动将列转换为摄氏度
f_to_c <- function(df){
df[["XH_warmed_air_1m"]] <- fahrenheit.to.celsius(df[["XH_warmed_air_1m"]])
df[["XH_ambient_air_1m"]] <- fahrenheit.to.celsius(df[["XH_ambient_air_1m"]])
return(df)
}
我可以使用 lapply 将 function 应用于整个列表,但这会在 df3 的数据已经位于首位时将其转换为摄氏度
list <- lapply(list, f_to_c)
我想将此 function 仅应用于所需的数据帧,我在下面尝试这样做。 但是,这会导致错误消息# Error in df[["XH_warmed_air_1m"]]: subscript out of bounds
list <- lapply(list$df1, f_to_c)
我可以使用什么方法将此 function 仅应用于包含华氏温度的数据帧?
使用 R 版本 3.5.1,Mac OS X 10.13.6
您没有在代码中包含fahrenheit.to.celsius
function,所以我在这里添加了它:
fahrenheit.to.celsius <- function(x) (x - 32) / 1.8
您所做的就是将 function 应用于列表的子集,然后将其写回同一子集:
list[1:2] <- lapply(list[1:2], f_to_c)
list
#> $df1
#> XH_warmed_air_1m XH_ambient_air_1m
#> 1 15.55556 15.55556
#> 2 21.11111 21.11111
#> 3 26.66667 26.66667
#> 4 32.22222 32.22222
#> 5 37.77778 37.77778
#>
#> $df2
#> XH_warmed_air_1m XH_ambient_air_1m
#> 1 15.55556 15.55556
#> 2 21.11111 21.11111
#> 3 26.66667 26.66667
#> 4 32.22222 32.22222
#> 5 37.77778 37.77778
#>
#> $df3
#> XH_warmed_air_1m XH_ambient_air_1m
#> 1 0 0
#> 2 10 10
#> 3 20 20
#> 4 30 30
#> 5 40 40
作为脚注,拥有一个名为 list 的列表是一个非常糟糕的主意......
由代表 package (v0.3.0) 于 2020 年 7 月 15 日创建
我了解到您只想将 function 应用于列表中包含华氏温度的那些 DF。 唯一可以确定数据中的数字是摄氏度还是华氏度的值是温度本身。 所以我选择了最高温度需要低于 42 摄氏度的条件。
然后你可以用purrr
的keep
和map
很好地建立这个条件。
library(tidyverse)
df1 <- data.frame(XH_warmed_air_1m = c(60, 70, 80, 90, 100),
XH_ambient_air_1m = c(60, 70, 80, 90, 100))
df2 <- data.frame(XH_warmed_air_1m = c(60, 70, 80, 90, 100),
XH_ambient_air_1m = c(60, 70, 80, 90, 100))
df3 <- data.frame(XH_warmed_air_1m = c(0, 10, 20, 30, 40),
XH_ambient_air_1m = c(0, 10, 20, 30, 40))
list <- list(df1=df1, df2=df2, df3=df3)
fahrenheit.to.celsius <- function(x) (x - 32) / 1.8
f_to_c <- function(df){
df[["XH_warmed_air_1m"]] <- fahrenheit.to.celsius(df[["XH_warmed_air_1m"]])
df[["XH_ambient_air_1m"]] <- fahrenheit.to.celsius(df[["XH_ambient_air_1m"]])
return(df)
}
list %>%
keep(~{max(.x$XH_ambient_air_1m) > 42}) %>%
map(., f_to_c)
#> $df1
#> XH_warmed_air_1m XH_ambient_air_1m
#> 1 15.55556 15.55556
#> 2 21.11111 21.11111
#> 3 26.66667 26.66667
#> 4 32.22222 32.22222
#> 5 37.77778 37.77778
#>
#> $df2
#> XH_warmed_air_1m XH_ambient_air_1m
#> 1 15.55556 15.55556
#> 2 21.11111 21.11111
#> 3 26.66667 26.66667
#> 4 32.22222 32.22222
#> 5 37.77778 37.77778
另一种选择是map
library(purrr)
list[1:2] <- map(list[1:2], f_to_c)
您可以检查数据框是否包含以 F/C 为单位的温度。 我在这里假设如果任何值小于或等于 0,那么我们正在处理 C。
list <- lapply(list, function(x) ifelse(any(x <= 0.), x, f_to_c(x)))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.