簡體   English   中英

在 R 中使用應用函數而不是 for 循環

[英]Using apply functions instead of for loops in R

我一直在嘗試用 apply 函數替換我代碼中的 for 循環,我嘗試以所有可能的方式來做到這一點,使用 sapply 和 lapply 以及 apply 和 mapply,似乎總是不起作用,原始函數看起來像這個

ds1 <- data.frame(col1 = c(NA, 2), col2 = c("A", "B"))
ds2 <- data.frame(colA = c("A", "B"), colB = c(90, 110))

for(i in 1:nrow(ds1)){
  if(is.na(ds1$col1[i])){
    ds1$col1[i] <- ds2[ds2[,"colA"] == ds1$col2[i], "colB"]
  }
}

我最近對申請家庭的嘗試看起來像這樣

ds1 <- data.frame(col1 = c(NA, 2), col2 = c("A", "B"))
ds2 <- data.frame(colA = c("A", "B"), colB = c(90, 110))

sFunc <- function(x, y, z){
  if(is.na(x)){
    return(z[z[,"colA"] == y, "colB"])
  } else {
    return(x)
  }
}

ds1$col1 <- sapply(ds1$col1, sFunc, ds1$col2, ds2)

它為每一行返回ds2$colB ,有人可以向我解釋我在這方面做錯了什么嗎?

sapply僅迭代您傳遞的第一個向量。 您傳遞的其他參數將被視為每個循環中的整個向量。 遍歷在M ultiple載體需要ultivariate應用,這為m適用。

sFunc <- function(x, y){
  if(is.na(x)){
    return(ds2[ds2[,"colA"] == y, "colB"])
  } else {
    return(x)
  }
}

mapply(sFunc, ds1$col1, ds1$col2)
#> [1] 90  2

連接在這里很有用。 你可以在基礎 R 中做到這一點:

transform(merge(ds1, ds2, by.x = "col2", by.y = "colA"), 
          col1 = ifelse(is.na(col1), colB, col1))[names(ds1)]

#  col1 col2
#1   90    A
#2    2    B

或者用dplyr

library(dplyr)

inner_join(ds1, ds2, by = c("col2" = "colA")) %>%
    mutate(col1 = coalesce(col1, colB)) %>%
    select(names(ds1))

暫無
暫無

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

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