我有几个数据框,每个数据框包含温度数据,并放入列表中(如下所示是一些模拟数据):
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的数据已经以摄氏度为单位)。因此,我做了一个自动将列转换为摄氏度的功能
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将函数应用于整个列表,但这会把df3的数据转换为celsius从而弄乱了df3的数据
list <- lapply(list, f_to_c)
我只想将此功能应用于所需的数据框,下面我尝试这样做。但是,这会导致错误消息# Error in df[["XH_warmed_air_1m"]] : subscript out of bounds
list <- lapply(list$df1, f_to_c)
我可以使用什么方法将此功能仅应用于包含华氏温度的数据帧?
使用R版本3.5.1,Mac OS X 10.13.6
答案 0 :(得分:2)
您没有在代码中包含fahrenheit.to.celsius
函数,因此我在这里添加了它:
fahrenheit.to.celsius <- function(x) (x - 32) / 1.8
您要做的就是将函数应用于列表的子集,并将其写回到同一子集:
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 ...的列表是一个非常糟糕的主意。
由reprex package(v0.3.0)于2020-07-15创建
答案 1 :(得分:1)
我了解到,您只想将此功能应用于列表中包含华氏温度的DF。唯一可以识别数据值是摄氏度还是华氏度的值就是温度本身。因此我选择了最高温度必须低于42摄氏度的条件。
然后,您可以使用keep
中的map
和purrr
很好地建立此条件。
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
答案 2 :(得分:0)
另一个选项是map
library(purrr)
list[1:2] <- map(list[1:2], f_to_c)
答案 3 :(得分:0)
您可以检查数据框是否包含F / C温度。我在这里假设,如果任何值小于或等于0,那么我们正在处理C。
list <- lapply(list, function(x) ifelse(any(x <= 0.), x, f_to_c(x)))