簡體   English   中英

根據r中同一數據框中其他兩列的值添加一列

[英]Add a column based on the values of other two columns in the same data frame in r

假設我有一個包含三個變量的數據框,例如,我想添加第四個變量,其值基於第二個和第三個變量的值。 如果var2 = var3,則var4 = 3,如果var2 = Y,並且var3 = NA,則var4 = 1,如果var2 = NA,並且var3 = Y,則var4 = 2。

var1 var2 var3
m01  Y    NA    
m02  Y    NA
m03  NA   Y
m04  NA   Y
m05  Y    Y
m06  Y    NA
m07  Y    Y

我想要一個這樣的數據框:

var1 var2 var3 var4
m01  Y    NA   1
m02  Y    NA   1
m03  NA   Y    2
m04  NA   Y    2
m05  Y    Y    3
m06  Y    NA   1
m07  Y    Y    3

我正在嘗試ifelse但沒有成功。

有任何想法嗎?

每個人都忘記了舊的不良interaction

c(3,2,1,4)[interaction(lapply(dat[-1], is.na))]
#[1] 1 1 2 2 3 1 3

嘗試這個:

library(dplyr)
df <- data.frame(var1 = paste0("m0",1:7), 
             var2 = c(rep("Y",2) ,rep(NA, 2), rep("Y", 3)),
             var3 = c(rep(NA, 2), rep("Y", 3), NA, "Y"))
mutate(df, var4 = if_else(var2 ==  "Y", 
                      if_else(var3 == "Y", 3, 1,1), 
                      2, 2))

if_else軟件包中的dplyr也可以處理數字缺失(NA)的情況

少數選項:

df <- read.table(text = 'var1 var2 var3
m01  Y    NA    
m02  Y    NA
m03  NA   Y
m04  NA   Y
m05  Y    Y
m06  Y    NA
m07  Y    Y', head = TRUE, stringsAsFactors = FALSE)

典型的基礎R方法是apply遍歷必要列的行式迭代。 這是在無聲地強制轉換為矩陣,這就是為什么有些人避免使用這種方法的原因。

apply(df[-1], 1, function(x){sum(which(x == 'Y'))})
#> [1] 1 1 2 2 3 1 3

您可以使用rowwise將其轉換為rowwise ,它不會強制轉換為矩陣,但通常不是最快的方法:

library(dplyr)

df %>% 
    rowwise() %>% 
    mutate(var4 = sum(which(c(var2, var3) == 'Y')))
#> Source: local data frame [7 x 4]
#> Groups: <by row>
#> 
#> # A tibble: 7 x 4
#>    var1  var2  var3  var4
#>   <chr> <chr> <chr> <int>
#> 1   m01     Y  <NA>     1
#> 2   m02     Y  <NA>     1
#> 3   m03  <NA>     Y     2
#> 4   m04  <NA>     Y     2
#> 5   m05     Y     Y     3
#> 6   m06     Y  <NA>     1
#> 7   m07     Y     Y     3

對於因數(通過c轉換為整數),這也會按原樣失敗,但是可以預先或在內部將其強制轉換,或者可以使用is.na而不是檢查相等性。

更多有創意的基本選項包括將各列粘貼在一起以創建一個可以故意變平的因子,以強制轉換為整數:

as.integer(factor(paste0(df$var2, df$var3), levels = c('YNA', 'NAY', 'YY')))
#> [1] 1 1 2 2 3 1 3

或使用do.call將函數列表和df每個所需變量(用c mapply平)傳遞給mapply

do.call(mapply, 
        c(function(...){sum(which(!is.na(c(...))))}, 
          df[-1], 
          USE.NAMES = FALSE))
#> [1] 1 1 2 2 3 1 3

如果您確實需要ifelse邏輯, dplyr::case_when可以使用dplyr::case_when使用級聯條件而不使用混亂的語法:

df %>% mutate(var4 = case_when(var2 == 'Y' & var3 == 'Y' ~ 3,
                               var2 == 'Y' ~ 1, 
                               var3 == 'Y' ~ 2))
#>   var1 var2 var3 var4
#> 1  m01    Y <NA>    1
#> 2  m02    Y <NA>    1
#> 3  m03 <NA>    Y    2
#> 4  m04 <NA>    Y    2
#> 5  m05    Y    Y    3
#> 6  m06    Y <NA>    1
#> 7  m07    Y    Y    3

使用ifelse:

df$var4 <- ifelse(df$var2 == df$var3, 3, 
             ifelse(df$var3 == "NA" & df$var2 == "y", 1, 
               ifelse(df$var2 == "NA" & df$var3 == "y", 2, "?")))

如果“ NA”是因子值,則可以使用。 否則,將df$var3 == "NA"替換為is.na(df$var3) ,將df$var2 == "NA"替換為is.na(df$var2)

暫無
暫無

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

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