2017-08-01 67 views
2

我有類似下面的一個數據幀,除了我有17個變量(如Var1Var2),而不是2採用相同的標準在許多列計算新列

df <- read.table(header = TRUE, text = 
      "STUD_ID  Var1 Var2 
       1   0  0 
       1   0  1 
       2   1  2 
       3   3  0", stringsAsFactors = FALSE) 

我想如果17個變量中的任何一個具有值1,2或3,則創建輸出「是」的新列,否則創建「否」。我所需的輸出是:

# STUD_ID  Var1 Var2 Output 
#  1   0  0 "No" 
#  1   0  1 "Yes" 
#  2   1  2 "Yes" 
#  3   3  0 "Yes" 

我試着下面的代碼,但它給人的錯誤,我不希望部分粘貼複製的代碼的17倍:

df %>% 
    mutate(output = if_else(var1 %in% 1:3 | 
          var2 %in% 1:3, 1, 0)) 

回答

2

我們可以使用base R

df$Output <- c("No", "Yes")[Reduce(`|`, lapply(df[-1], `%in%`, 1:3)) + 1] 
df$Output 
#[1] "No" "Yes" "Yes" "Yes" 

或用tidyverse

library(tidyverse) 
df %>% 
    mutate_at(vars(matches("Var")), funs(. %in% 1:3)) %>% 
    select(-STUD_ID) %>% 
    reduce(`|`) %>% {c('No', 'Yes')[. + 1]} %>% 
    mutate(df, output = .) 
# STUD_ID Var1 Var2 output 
#1  1 0 0  No 
#2  1 0 1 Yes 
#3  2 1 2 Yes 
#4  3 3 0 Yes 
1

一種選擇將是以下:

df$Output = sapply(seq(1,nrow(df)), 
      function(x) {ifelse(any(df[x,c(2:3)] %in% c(1,2,3)),"Yes","No")}) 

您可以用列索引的範圍,或者與列名的數組替換c(2:3)。希望這可以幫助。

2

的一種方式,試圖做到這一點的矢量地(但仍效率不高,因爲它轉換爲字符串)是使用do.call粘貼您需要的行和grepl的值,即

ifelse(grepl('1|2|3', do.call(paste0, df[-1])), 'Yes', 'No') 
#[1] "No" "Yes" "Yes" "Yes" 
1

可以添加所有的17個變量,而如果總和大於0,則它意味着ATLEAST一個非零值在那裏

> df$VarNew=df$Var1+df$Var2 
> df 
    STUD_ID Var1 Var2 VarNew 
1  1 0 0  0 
2  1 0 1  1 
3  2 1 2  3 
4  3 3 0  3 
> df$VarNew2=ifelse(df$VarNew>0,"Yes","No") 
> df 
    STUD_ID Var1 Var2 VarNew VarNew2 
1  1 0 0  0  No 
2  1 0 1  1  Yes 
3  2 1 2  3  Yes 
4  3 3 0  3  Yes 
+1

假設數字都是非負的和正的值是唯一的在{1,2,3}中,則一個班輪將是'ifelse(rowSums(df [-1])> 0,「是」,「否」)。 – lmo