我有大量資料框串列,其中包含來自不同地區的環境變數。對于串列中的每個資料框,我想匯總跨地區的值(= 將同一地區的測量值組合為一個),使用資料框的名稱作為需要匯總變數的條件。例如,對于名稱為“鹽度”的資料框,我只想總結鹽度,而不是其他環境變數。請注意,不同的資料幀包含來自不同地區的資料,因此我不能簡單地將它們合并到一個資料幀中。
讓我們用一個虛擬資料集來做這件事:
#create list of dataframes
df1 = data.frame(locality = c(1, 2, 2, 5, 7, 7, 9),
Temp = c(14, 15, 16, 18, 20, 18, 21),
Sal = c(16, NA, NA, 12, NA, NA, 9))
df2 = data.frame(locality = c(1, 1, 3, 6, 8, 9, 9),
Temp = c(1, 2, 4, 5, 0, 2, -1),
Sal = c(18, NA, NA, NA, 36, NA, NA))
df3 = data.frame(locality = c(1, 3, 4, 4, 5, 5, 9),
Temp = c(14, NA, NA, NA, 17, 18, 21),
Sal = c(16, 8, 24, 23, 11, 12, 9))
df4 = data.frame(locality = c(1, 1, 1, 4, 7, 8, 10),
Temp = c(1, NA, NA, NA, NA, 0, 2),
Sal = c(18, 17, 13, 16, 20, 36, 30))
df_list = list(df1, df2, df3, df4)
names(df_list) = c("Summer_temperature", "Winter_temperature",
"Summer_salinity", "Winter_salinity")
接下來,我用 lapply 總結了環境變數:
#select only those dataframes in the list that have either 'salinity' or 'temperature' in the dataframe names
df_sal = df_list[grep("salinity", names(df_list))]
df_temp = df_list[grep("temperature", names(df_list))]
#use apply to summarize salinity or temperature values in each dataframe
##salinity
df_sal2 = lapply(df_sal, function(x) {
x %>%
group_by(locality) %>%
summarise(Sal = mean(Sal, na.rm = TRUE))
})
##temperature
df_temp2 = lapply(df_temp, function(x) {
x %>%
group_by(locality) %>%
summarise(Temp = mean(Temp, na.rm = TRUE))
})
現在,這段代碼是重復的,所以我想通過將所有內容組合成一個函式來縮小它的大小。這是我嘗試過的:
df_env = lapply(df_list, function(x) {
if (grepl("salinity", names(x)) == TRUE) {x %>% group_by(locality) %>% summarise(Sal = mean(Sal, na.rm = TRUE))}
if (grepl("temperature", names(x)) == TRUE) {x %>% group_by(locality) %>% summarise(Temp = mean(Temp, na.rm = TRUE))}
})
但我得到以下輸出:
$Summer_temperature
NULL
$Winter_temperature
NULL
$Summer_salinity
NULL
$Winter_salinity
NULL
以及以下警告訊息:
Warning messages:
1: In if (grepl("salinity", names(x)) == TRUE) { :
the condition has length > 1 and only the first element will be used
2: In if (grepl("temperature", names(x)) == TRUE) { :
the condition has length > 1 and only the first element will be used
3: In if (grepl("salinity", names(x)) == TRUE) { :
the condition has length > 1 and only the first element will be used
4: In if (grepl("temperature", names(x)) == TRUE) { :
the condition has length > 1 and only the first element will be used
5: In if (grepl("salinity", names(x)) == TRUE) { :
the condition has length > 1 and only the first element will be used
6: In if (grepl("temperature", names(x)) == TRUE) { :
the condition has length > 1 and only the first element will be used
7: In if (grepl("salinity", names(x)) == TRUE) { :
the condition has length > 1 and only the first element will be used
8: In if (grepl("temperature", names(x)) == TRUE) { :
the condition has length > 1 and only the first element will be used
現在,我在這里讀到這個警告訊息可以通過使用來解決ifelse。然而,在最終的資料集中,我將有兩個以上的環境變數,所以我將不得不添加更多的if陳述句——因此我認為ifelse這不是一個解決方案。有人對我的問題有一個優雅的解決方案嗎?我是使用函式和 lapply 的新手,如果你能給我任何幫助,我將不勝感激。
編輯:
我嘗試使用答案之一中建議的 else if 選項,但這仍然回傳 NULL 值。我也嘗試了回傳并將輸出分配給 x 但兩者都有與下面的代碼相同的問題 - 有什么想法嗎?
#else if
df_env = lapply(df_list, function(x) {
if (grepl("salinity", names(x)) == TRUE) {
x %>% group_by(locality) %>%
summarise(Sal = mean(Sal, na.rm = TRUE))}
else if (grepl("temperature", names(x)) == TRUE) {
x %>% group_by(locality) %>%
summarise(Temp = mean(Temp, na.rm = TRUE))}
})
df_env
我認為正在發生的事情是我的 if 引數沒有傳遞給 summarise 函式,因此沒有任何內容被匯總。
uj5u.com熱心網友回復:
這里發生了幾件事,包括
正如akrun所說,
if陳述句必須有一個長度為1的條件。你的不是。grepl("locality", names(df1)) # [1] TRUE FALSE FALSE必須減少它,以便它始終是長度 1。坦率地說,
grepl這里是錯誤的工具,因為從技術上講,一個名為的列notlocality會匹配,然后它會出錯。我建議你改成"locality" %in% names(df1) # [1] TRUE你需要回傳一些東西。總是。您從 轉移
if ...; if ...;到if ... else if ...,這是一個好的開始,但實際上如果您不滿足任何條件,則不會回傳任何內容。我建議使用以下方法之一:或者再添加一個} else x,或者重新分配 asif (..) { x <- x %>% ...; } else if (..) { x <- x %>% ... ; }然后用 just 結束 anon-funcx(回傳它)。
但是,我認為最終的問題是您正在尋找"temperature"或"salinity"在list-objects 的名稱中,而不是在框架本身中。例如,您對names(x)回傳的參考是c("locality", "Temp", "Sal")框架x本身的名稱。
我想這就是你想要的?
Map(function(x, nm) {
if (grepl("salinity", nm)) {
x %>%
group_by(locality) %>%
summarize(Sal = mean(Sal, na.rm = TRUE))
} else if (grepl("temperature", nm)) {
x %>%
group_by(locality) %>%
summarize(Temp = mean(Temp, na.rm = TRUE))
} else x
}, df_list, names(df_list))
# $Summer_temperature
# # A tibble: 5 x 2
# locality Temp
# <dbl> <dbl>
# 1 1 14
# 2 2 15.5
# 3 5 18
# 4 7 19
# 5 9 21
# $Winter_temperature
# # A tibble: 5 x 2
# locality Temp
# <dbl> <dbl>
# 1 1 1.5
# 2 3 4
# 3 6 5
# 4 8 0
# 5 9 0.5
# $Summer_salinity
# # A tibble: 5 x 2
# locality Sal
# <dbl> <dbl>
# 1 1 16
# 2 3 8
# 3 4 23.5
# 4 5 11.5
# 5 9 9
# $Winter_salinity
# # A tibble: 5 x 2
# locality Sal
# <dbl> <dbl>
# 1 1 16
# 2 4 16
# 3 7 20
# 4 8 36
# 5 10 30
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/482625.html
