簡體   English   中英

根據R中的條件合並數據框中的多列

[英]Merging multiple columns in a dataframe based on condition in R

我對R非常陌生,我想執行以下操作:

我有一個包含ID, Col1, Col2, Col3列的數據框。

df <- read.table(header = TRUE, stringsAsFactors = FALSE, text="
ID Col1    Col2                        Col3             
1  0       'Less than once a month'    0               
2  Never   0                           0              
3  0       0                           'Once a month'
")

我想將這3列合並為一個,其中如果"Never"和其他列為0 ,則值為"Never" ,如果"Once a month" ,其余為0 ,則"Once a month"等等。 所有列都是互斥的,這意味着同一原始數據中不能有"Never""Once a month"

 //I tried to apply this loop:

         for (val in df) {
if(df$Col1 == "Never" && df$Col2 == "0")
  {
  df$consolidated <- "Never"
  } else (df$`Col1 == "0" && df$Col2 == "Less than once a month")
  {
  how_oft_purch_gr_pers$consolidated <- "Less than once a month"
  }
}

我只想首先計算兩列,但沒有用,因為合並列中的所有原始數據都填充為“每月少於一次”。

我希望它是這樣的:

ID Col1    Col2                       Col3             Consolidated
1  0       Less than once a month       0              Less than once a month
2  Never   0                            0              Never
3  0       0                            Once a month   Once a month

關於我在做什么錯的任何提示嗎?

先感謝您

將NA替換為0后,您可以考慮使用dplyr::coalesce coalesce()查找第一個非缺失值(在本例中為行)並創建一個新列。 解決方案可以是:

library(dplyr)

df %>% mutate_at(vars(starts_with("Col")), funs(na_if(.,"0"))) %>%
  mutate(Consolidated = coalesce(Col1,Col2,Col3)) %>%
  select(ID, Consolidated)

# OR in concise way once can simply write as
bind_cols(df[1], Consolidated = coalesce(!!!na_if(df[-1],"0")))

#   ID           Consolidated
# 1  1 Less than once a month
# 2  2                  Never
# 3  3           Once a month

數據:

df <- read.table(text = 
"ID Col1    Col2                       Col3             
1  0       'Less than once a month'       0               
2  Never   0                            0              
3  0       0                            'Once a month'",
stringsAsFactors = FALSE, header = TRUE)

即使@MKR編寫了一個很好的答案,我也想指出您的代碼中的一些錯誤,這可能是它不起作用的原因

for (val in df) {

您可能想遍歷df所有行。 但是,實際上,您正在遍歷數據框的 原因是數據幀是向量(您的列)的列表,所有向量都必須具有相同的長度。 使用您的代碼,您可以遍歷列的df元素。 有關數據框的每一行,請參見問答

  if(df$Col1 == "Never" && df$Col2 == "0"){

請注意,當使用雙&&而不是& ,R僅查看您賦予它的向量的第一個元素。 參見例如Q&A 布爾運算符&&和||

    df$consolidated <- "Never"

在這里,您將df consolidated的整個列設置為"Never" ,因為您沒有從上面使用迭代var (即使它代表一個df行,但它並不代表您寫的那樣)。

  } else (df$`Col1 == "0" && df$Col2 == "Less than once a month"){
  • 您需要使用else if(...) ,而不是else (...) 就像您寫的一樣, if(...)上面的if(...)不正確,R會認為應該執行(....)的語句,而if之后的{...}的語句將被R視為與if... else...構造無關,因為它已經執行(...) 因此,無論上述if(...)的結果如何,它將始終執行{...}塊。

  • df$`Col1是錯字嗎? 反引號`只能成對出現,並且可以在變量(以及列名)周圍使用

    df$consolidated <- "Less than once a month"

如上所述,您在此處再次將整個列設置為一個值。

  } 
}

這是使用基數R的可能性

開始您的結果列。 僅用"0"初始化它。

df$coalesced <- "0"

循環瀏覽df某些列(Col1–Col3)。 如果您可能只使用一列,請使用drop = FALSE ,因為R在這種情況下將輸出一個向量,並且for會在該向量的元素上循環,而在那種情況下不會在單個列上循環。

for( column in d[, c("Col1","Col2","Col3"), drop = FALSE]){

這將檢查每個coalesced是否已填充,如果沒有,則檢查(如果為"0"則將其填充當前列(也可以為"0" ))

    df$coalesced <- ifelse(df$coalesced == "0", column, df$coalesced)

}

將新列添加到數據框

df$coalesced <- coalesced

暫無
暫無

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

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