[英]Remove multiple columns and replace values of columns of dataframe based on condition in 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.