Как я могу превратить эти аргументы множественного присваивания в функцию в R? Заполните столбец значениями, зависящими от вида - PullRequest
0 голосов
/ 08 октября 2019

В моей работе мне нужно присвоить оценку новому столбцу. Числовое значение этой оценки зависит от вида.

В настоящее время у меня есть следующий метод для достижения этой цели, который работает, но не очень лаконичен для многократного использования с несколькими наборами данных:

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

и пр. ......

Большое спасибо.

Ответы [ 3 ]

1 голос
/ 08 октября 2019

Как упоминает @Gregor с помощью языка SQL, сохраните данные индикатора в справочной таблице , а затем merge в исходной таблице в соотношении один-ко-многим, которое масштабируется до 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, чтобы сохранить все исходные строки независимо от совпадений со второй таблицей. Затем сделайте необходимое присваивание (NA значения для несоответствий) и удалите искомое значение:

bird <- within(merge(bird, species_vis_df, by="species", all.x=TRUE), {
               VIS <- value
               rm(value)
        })
0 голосов
/ 08 октября 2019

Другой пример использования логики 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))))))
0 голосов
/ 08 октября 2019

Вы могли бы предложить очень простой воспроизводимый пример, который я привожу здесь:

DT <- data.frame(V1 = LETTERS[1:10])

Вы хотите дать оценку для каждой конкретной переменной V1 в новой переменной (VIS).

решение dplyr с case_when

library(dplyr)
DT = DT %>% 
  mutate(VIS=case_when(
    V1=="A"~0.1,
    V1=="B"~0.2 #and so on
  ))

DT
...