如何将这些多值赋值参数转换为 R 中的函数?用依赖于物种的值填充一列
How can I turn these multiple value assignment arguments into a function in R? Populate a column with species dependent values
在我的工作中,我需要为一个新的列分配一个分数。该分数的数值因物种而异。
目前,我有以下方法可以实现此目的,但对于重复使用多个数据集来说不是很简洁:
bird$VIS <- 0 # creates the new column and populates it with 0
bird$VIS[bird$species == "Tyto alba" ] <- 0.0502 # assigns this score to the VIS column for rows where the species is "Tyto alba"
bird$VIS[bird$species == "Branta leucopsis" ] <- 0.044
bird$VIS[bird$species == "Ciconia nigra" ] <- 0.002
bird$VIS[bird$species == "Grus grus" ] <- 0.001
bird$VIS[bird$species == "Bubo bubo" ] <- 0.004513
bird$VIS[bird$species == "Neophron percnopterus" ] <- 0.0015333
bird$VIS[bird$species == "Platalea leucorodia" ] <- 0.001
以此类推,总共有 26 个物种,但这个子样本应该足以证明我正在尝试做的事情。
我的问题本质上是如何将它变成一个函数,无论所有物种是否都存在于数据框中,它都可以工作?
本质上,我希望能够编写如下内容,而不是使用上述顺序行分配:
assign_VIS_function(bird)
导致输出类似于:
SPECIES VIS
Branta leucopsis 0.044
Tyto alba 0.0502
Tyto alba 0.0502
Tyto alba 0.0502
Tyto alba 0.0502
Gyps fulvus 0.22838
Gyps fulvus 0.22838
Gyps fulvus 0.22838
等等……
非常感谢。
您实际上可以提出一个非常简单的可重现示例,我在这里给出:
DT <- data.frame(V1 = LETTERS[1:10])
您想在新变量 (VIS) 上为 V1 的每个特定变量打分。
一个 dplyr 解决方案 case_when
library(dplyr)
DT = DT %>%
mutate(VIS=case_when(
V1=="A"~0.1,
V1=="B"~0.2 #and so on
))
DT
另一个使用 ifelse() 逻辑的例子。你看,如果你不为“Platalea
leucorodia”或其他什么物种,它们将被归为 0(在代码的最后)。
data<-data_frame(birds=c("Grus grus","Bubo bubo","Grus grus","Bubo bubo","Platalea
leucorodia"))
data %>%
mutate(VIS = ifelse(birds == "Tyto alba", 0.0502 ,
ifelse(birds == "Branta leucopsis" , 0.044 ,
ifelse(birds == "Ciconia nigra" , 0.002,
ifelse(birds == "Grus grus", 0.001,
ifelse(birds == "Bubo bubo", 0.004513 , 0))))))
正如@Gregor 在 SQL 中提到的那样,将指标数据保存在 查找 table 中,然后 merge
到原始 table 在扩展到 26 或 260 个项目的一对多关系中:
species_vis_df <- data.frame(species = c("Tyto alba", "Branta leucopsis", "Ciconia nigra",
"Grus grus", "Bubo bubo", "Neophron percnopterus",
"Platalea leucorodia"),
value = c(0.0502 , 0.044, 0.002, 0.001,
0.004513, 0.0015333, 0.001))
或者。表格格式:
txt = 'species value
"Tyto alba" 0.0502
"Branta leucopsis" 0.044
"Ciconia nigra" 0.002
"Grus grus" 0.001
"Bubo bubo" 0.004513
"Neophron percnopterus" 0.0015333
"Platalea leucorodia" 0.001'
species_vis_df <- read.table(text = txt, header=TRUE)
species_vis_df
# species value
# 1 Tyto alba 0.0502000
# 2 Branta leucopsis 0.0440000
# 3 Ciconia nigra 0.0020000
# 4 Grus grus 0.0010000
# 5 Bubo bubo 0.0045130
# 6 Neophron percnopterus 0.0015333
# 7 Platalea leucorodia 0.0010000
然后 运行 merge
,专门借用 SQL 再次 left join
与 all.x=TRUE
合并以保留所有原始行,而不管与第二个匹配 table。之后,进行所需的分配(NA
不匹配的值)并删除查找值:
bird <- within(merge(bird, species_vis_df, by="species", all.x=TRUE), {
VIS <- value
rm(value)
})
在我的工作中,我需要为一个新的列分配一个分数。该分数的数值因物种而异。
目前,我有以下方法可以实现此目的,但对于重复使用多个数据集来说不是很简洁:
bird$VIS <- 0 # creates the new column and populates it with 0
bird$VIS[bird$species == "Tyto alba" ] <- 0.0502 # assigns this score to the VIS column for rows where the species is "Tyto alba"
bird$VIS[bird$species == "Branta leucopsis" ] <- 0.044
bird$VIS[bird$species == "Ciconia nigra" ] <- 0.002
bird$VIS[bird$species == "Grus grus" ] <- 0.001
bird$VIS[bird$species == "Bubo bubo" ] <- 0.004513
bird$VIS[bird$species == "Neophron percnopterus" ] <- 0.0015333
bird$VIS[bird$species == "Platalea leucorodia" ] <- 0.001
以此类推,总共有 26 个物种,但这个子样本应该足以证明我正在尝试做的事情。
我的问题本质上是如何将它变成一个函数,无论所有物种是否都存在于数据框中,它都可以工作?
本质上,我希望能够编写如下内容,而不是使用上述顺序行分配:
assign_VIS_function(bird)
导致输出类似于:
SPECIES VIS
Branta leucopsis 0.044
Tyto alba 0.0502
Tyto alba 0.0502
Tyto alba 0.0502
Tyto alba 0.0502
Gyps fulvus 0.22838
Gyps fulvus 0.22838
Gyps fulvus 0.22838
等等……
非常感谢。
您实际上可以提出一个非常简单的可重现示例,我在这里给出:
DT <- data.frame(V1 = LETTERS[1:10])
您想在新变量 (VIS) 上为 V1 的每个特定变量打分。
一个 dplyr 解决方案 case_when
library(dplyr)
DT = DT %>%
mutate(VIS=case_when(
V1=="A"~0.1,
V1=="B"~0.2 #and so on
))
DT
另一个使用 ifelse() 逻辑的例子。你看,如果你不为“Platalea leucorodia”或其他什么物种,它们将被归为 0(在代码的最后)。
data<-data_frame(birds=c("Grus grus","Bubo bubo","Grus grus","Bubo bubo","Platalea
leucorodia"))
data %>%
mutate(VIS = ifelse(birds == "Tyto alba", 0.0502 ,
ifelse(birds == "Branta leucopsis" , 0.044 ,
ifelse(birds == "Ciconia nigra" , 0.002,
ifelse(birds == "Grus grus", 0.001,
ifelse(birds == "Bubo bubo", 0.004513 , 0))))))
正如@Gregor 在 SQL 中提到的那样,将指标数据保存在 查找 table 中,然后 merge
到原始 table 在扩展到 26 或 260 个项目的一对多关系中:
species_vis_df <- data.frame(species = c("Tyto alba", "Branta leucopsis", "Ciconia nigra",
"Grus grus", "Bubo bubo", "Neophron percnopterus",
"Platalea leucorodia"),
value = c(0.0502 , 0.044, 0.002, 0.001,
0.004513, 0.0015333, 0.001))
或者。表格格式:
txt = 'species value
"Tyto alba" 0.0502
"Branta leucopsis" 0.044
"Ciconia nigra" 0.002
"Grus grus" 0.001
"Bubo bubo" 0.004513
"Neophron percnopterus" 0.0015333
"Platalea leucorodia" 0.001'
species_vis_df <- read.table(text = txt, header=TRUE)
species_vis_df
# species value
# 1 Tyto alba 0.0502000
# 2 Branta leucopsis 0.0440000
# 3 Ciconia nigra 0.0020000
# 4 Grus grus 0.0010000
# 5 Bubo bubo 0.0045130
# 6 Neophron percnopterus 0.0015333
# 7 Platalea leucorodia 0.0010000
然后 运行 merge
,专门借用 SQL 再次 left join
与 all.x=TRUE
合并以保留所有原始行,而不管与第二个匹配 table。之后,进行所需的分配(NA
不匹配的值)并删除查找值:
bird <- within(merge(bird, species_vis_df, by="species", all.x=TRUE), {
VIS <- value
rm(value)
})