簡體   English   中英

根據另一個因素的水平改變一個因素的水平

[英]Change the level of a factor based on the level of another factor

我有一個包含許多變量的數據集,其中兩個稱為“動物”和“植物”。 兩個變量都是因子,都是二元的,即它們要么是文本值,要么是 NA。

例如:

animal <- c(NA, NA, "cat", "cat", NA)
plant  <- c("ivy", NA, "ivy", NA, NA)
value  <- c(1:5)
df     <- data.frame(animal, plant, value)

> df
  animal plant value
1   <NA>   ivy     1
2   <NA>  <NA>     2
3    cat   ivy     3
4    cat  <NA>     4
5   <NA>  <NA>     5

當植物的價值是“常春藤”而動物的價值是“貓”時,我想將植物的價值改為NA(即這兩件事不能為真,動物價值優先。我不'我的其他變量沒有任何變化

我嘗試了以下操作,但收到一條錯誤消息:

df <- df %>% if (isTRUE(animal == "cat")) {plant==NA}

Error in if (.) isTRUE(animal == "cat") else { : 
  argument is not interpretable as logical
In addition: Warning message:
In if (.) isTRUE(animal == "cat") else { :
  the condition has length > 1 and only the first element will be used

我的目標輸出是:

> df
  animal plant value
1   <NA>   ivy     1
2   <NA>  <NA>     2
3    cat  <NA>     3
4    cat  <NA>     4
5   <NA>  <NA>     5

我真的很感激任何幫助。 我確信有一種非常簡單的方法可以做到這一點,也許我只見樹木不見森林。

library(dplyr)    

df %>% 
      mutate(plant = case_when(animal == 'cat' & plant == 'ivy' ~ NA_character_,
                               TRUE ~ plant))

這給了我們:

  animal plant value
1   <NA>   ivy     1
2   <NA>  <NA>     2
3    cat  <NA>     3
4    cat  <NA>     4
5   <NA>  <NA>     5

你也可以這樣做:

df[!(is.na(df$animal)|is.na(df$plant)),'plant'] <- NA
df
  animal plant value
1   <NA>   ivy     1
2   <NA>  <NA>     2
3    cat  <NA>     3
4    cat  <NA>     4
5   <NA>  <NA>     5

這也可以表示為:

df[!is.na(df$animal) & !is.na(df$plant),'plant'] <- NA

你的問題似乎比你想象的要簡單。 您可以通過將所有植物(動物不是NA )轉換為NA來實現相同的結果:

df$plant[!is.na(df$animal)] <- NA

或者更高級一點:

is.na(df$plant) <- !is.na(df$animal)

這里的問題是==不適用於 R 中的NA值。

> df[df$animal=="cat",]
     animal plant value
NA     <NA>  <NA>    NA
NA.1   <NA>  <NA>    NA
3       cat   ivy     3
4       cat  <NA>     4
NA.2   <NA>  <NA>    NA

例如,這里返回所有行,因為NA == "ANYTHING"返回NA

您可以定義這個函數,如果xy相等而不是NA ,或者兩者都是NA ,則該函數返回TRUE

is.equal.force <- `%===%` <- function(x,y, vect=T) {
  res <- ifelse(is.na(x),is.na(y),ifelse(!is.na(y)&!is.na(x),x==y, NA))
  if(!vect){
    res <- all(res)
  }
  return(res)
}

那么您的問題的解決方案就變得很簡單:

df[df$animal%===%"cat"&df$plant%===%"ivy","plant"] <- NA
df
  animal plant value
1   <NA>   ivy     1
2   <NA>  <NA>     2
3    cat  <NA>     3
4    cat  <NA>     4
5   <NA>  <NA>     5

請注意,此處使用了正確的語法。

暫無
暫無

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

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