簡體   English   中英

如何將相同的 function 應用於 R 中的幾個變量?

[英]How to apply the same function to several variables in R?

我知道已經問過類似的問題(例如,將列表元素名稱作為變量傳遞給 lapplyR 中的函數 - 迭代地應用變量列表的 function ),但我無法找到基於我的問題的解決方案在這些帖子上。

我有一個事件數據集(約 100 個變量,>2000 個觀察值),其中包含包含有關參與者信息的變量。 一個變量只能包含一個參與者,因此如果事件中涉及了多個參與者,它們將分布在多個變量中(例如actor1actor2 、...)。 這些演員可以分為兩組(“s”和“nons”)。 為了以后使用,我需要兩個演員列表:一個包含“s”類別的所有演員,另一個包含“nons”類別的所有演員。 “s”僅由三個演員組成,而“nons”由數十個演員組成。

# create example data
df <- data.frame(id = c(1:8),
                 actor1 = c("A", "B", "D", "E", "F", "G", "H", NA),
                 actor2 = c("A", NA, "B", "C", "E", "I", "D", "G"))

df <-  
  df %>%
  mutate(actor1 = as.character(actor1),
         actor2 = as.character(actor2))

由於我即將准備的腳本應該在未來用於數據集的更新版本,我想盡可能地自動化,並盡可能限制腳本中需要調整的部分。 我的想法是為每個類別創建一個 function 從列表中的一個變量(例如actor1 )中提取相應類別的參與者(例如“nons”),然后在其他變量上“循環”這個 function(理想情況下使用apply系列)。

我知道每個演員屬於哪個類別(“A”、“B”和“C”是類別“s”),這允許我定義一個分隔規則,如下面的 function 中使用的(過濾器命令)。

# create function
nons_function <- function(col) {
  col_ <- enquo(col)
  nons_list <-
    df %>%
    filter(!is.na(!!col_), !!col_ != "A", !!col_ != "B", !!col_ != "C") %>%
    distinct(!!col_) %>%
    pull()
  nons_list
}

# create list of variables to "loop" over
actorlist <- c("actor1", "actor2")

這導致以下結果。 我得到一個包含變量名稱作為字符串的列表,而不是兩個演員列表。

> lapply(actorlist, nons_function)
[[1]]
[1] "actor1"

[[2]]
[1] "actor2"

我想得到的是如下內容:

> lapply(actorlist, nons_function)
[[1]]
[1] "D" "E" "F" "G" "H"

[[2]]
[1] "E" "I" "D" "G"

問題可能是我將變量名稱傳遞給 lapply 內的function的方式。 顯然,我的 function 無法使用字符輸入作為變量名。 但是,我還沒有找到一種方法來調整我的 function 以允許字符輸入,或者為我的 function 提供一個變量列表,以便以它可以消化的方式循環。

任何幫助表示贊賞!

編輯:最初我以一種誤導性的方式命名了演員(演員名稱表明演員屬於哪個類別),這導致答案對我的情況沒有真正的幫助。 我現在將演員名稱從“s1”、“s2”、“nons1”、“nons2”等更改為“A”、“B”、“C”等。

這是使用基礎 r 的選項。

對於非演員:

lapply( df[, 2:3], function(x) grep( "^nons", x, value = TRUE ) )

#$actor1
#[1] "nons1" "nons2" "nons3" "nons4" "nons5"
#
#$actor2
#[1] "nons2" "nons6" "nons1" "nons4"

對於 s 演員:

lapply( df[, 2:3], function(x) grep( "^s", x, value = TRUE ) )

# $actor1
# [1] "s1" "s2"
# 
# $actor2
# [1] "s1" "s2" "s3"

這是一個選項

library(dplyr)
library(stringr)
library(purrr)
map(actorlist, ~ df %>% 
                  select(.x) %>%
                  filter(!str_detect(!! rlang::sym(.x), "^s\\d+$")) %>% 
                   pull(1))
#[[1]]
#[1] "nons1" "nons2" "nons3" "nons4" "nons5"

#[[2]]
#[1] "nons2" "nons6" "nons1" "nons4"

它也可以包裝為 function。 請注意,輸入是字符串,因此不要使用enquo ,而是使用sym轉換為符號然后計算 ( !! )

f1 <- function(dat, colNm) {
                dat %>%
                  select(colNm) %>%
                   filter(!str_detect(!! rlang::sym(colNm), "^s\\d+$")) %>%
                    pull(1) %>%
                    unique
         }

map(actorlist, f1, dat = df)

注意:這可以更容易地完成,但在這里我們使用來自 OP 帖子的類似代碼


另一種選擇是在base R splitgrepl一起使用,並在刪除NA后返回“nons”和“s”的list

lapply(df[2:3], function(x)  {
           x1 <- x[!is.na(x)]
            split(x1, grepl("nons", x1))})

檢查我的解決方案,看看它是否適合你。

require("dplyr")


# create example data
df <- data.frame(id = c(1:8),
                 actor1 = c("s1", "s2", "nons1", "nons2", "nons3", "nons4", "nons5", NA),
                 actor2 = c("s1", NA, "s2", "s3", "nons2", "nons6", "nons1", "nons4"))

df <-  
  df %>%
  mutate(actor1 = as.character(actor1),
         actor2 = as.character(actor2))


# Function for getting the category
category_function <- function(col,categ){

  if(categ == "non"){
    outp = grep("^non",col,value = T)
  }else{
    outp = grep("^s",col,value = T)
  }

  return(outp)  

}

# Apply the function to all variables whose name starts with "actor"
sapply(df[grep("actor",names(df),value=T)],category_function,categ="non")
sapply(df[grep("actor",names(df),value=T)],category_function,categ="s")

我的 output 如下:

> sapply(df[grep("actor",names(df),value=T)],category_function,categ="non")
$actor1
[1] "nons1" "nons2" "nons3" "nons4" "nons5"

$actor2
[1] "nons2" "nons6" "nons1" "nons4"

> sapply(df[grep("actor",names(df),value=T)],category_function,categ="s")
$actor1
[1] "s1" "s2"

$actor2
[1] "s1" "s2" "s3"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM