如何将这些多值赋值参数转换为 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 joinall.x=TRUE 合并以保留所有原始行,而不管与第二个匹配 table。之后,进行所需的分配(NA 不匹配的值)并删除查找值:

bird <- within(merge(bird, species_vis_df, by="species", all.x=TRUE), {
               VIS <- value
               rm(value)
        })