2016-12-05 73 views
2

我有一個數據框,其中某些列中的某些值的值被輸入爲'L'(對於太低而無法測量),其餘的值是數字。我想更換色譜柱內的「低」用最低的數值:r用一列中的最低數值替換列中的字符值

我有什麼:

A 4 6 5 L 
B 4 L 9 3 
C 6 7 6 5 
D L 8 L 3 

我想什麼:

A 4 6 5 3 
B 4 6 9 3 
C 6 7 6 5 
D 4 8 5 3 

我已經走了一條複雜的道路,生成一個查找表,然後嘗試將其應用於數據框中的所有列,並且我一直認爲必須有一個更簡單的方法。

任何幫助表示讚賞!謝謝你 -

回答

1

假設列character類,通過除了第一個列環,和replace的「L」與numeric元件min值,然後將其轉換爲numeric類。

df1[-1] <- lapply(df1[-1], function(x) as.numeric(replace(x, 
         x=="L", min(as.numeric(x), na.rm = TRUE)))) 
df1 
# v1 v2 v3 v4 v5 
#1 A 4 6 5 3 
#2 B 4 6 9 3 
#3 C 6 7 6 5 
#4 D 4 8 5 3 

順便說一句,使用lapply建議過apply因爲後者轉換到matrix


或者使用dplyr

library(dplyr) 
df1 %>% 
     mutate_each(funs(replace(., .=="L", min(.))), 2:5) 
# v1 v2 v3 v4 v5 
#1 A 4 6 5 3 
#2 B 4 6 9 3 
#3 C 6 7 6 5 
#4 D 4 8 5 3 

或者使用setdata.table這是非常有效的

library(data.table) 
setDT(df1) 
for(j in 2:ncol(df1)){ 
set(df1, i = which(df1[[j]]=="L"), j=j, value = min(df1[[j]])) 
} 
df1 
# v1 v2 v3 v4 v5 
#1: A 4 6 5 3 
#2: B 4 6 9 3 
#3: C 6 7 6 5 
#4: D 4 8 5 3 
+1

謝謝!第一個解決方案效果很好。我的'真實'數據中存在一些值,我忽略了在我的例子中將複雜的問題 - 例如NAs和3和10在同一列中選擇10作爲字符評估。你的代碼工作完美! – rshaw

1

我們可以apply縱列得到該列中的最小值和更換無論您在哪裏找到"L"

apply(df, 2, function(x) ifelse(x == "L", min(x), x)) 

#  V1 V2 V3 V4 V5 
#[1,] "A" "4" "6" "5" "3" 
#[2,] "B" "4" "6" "9" "3" 
#[3,] "C" "6" "7" "6" "5" 
#[4,] "D" "4" "8" "5" "3" 

這將返回一個matrix把它作爲數據幀

data.frame(apply(df, 2, function(x) ifelse(x == "L", min(x), x))) 

# V1 V2 V3 V4 V5 
#1 A 4 6 5 3 
#2 B 4 6 9 3 
#3 C 6 7 6 5 
#4 D 4 8 5 3 
1

隨着dplyr包,假設數據幀被稱爲dat和列名V1通過V5

library(dplyr) 

dat %>% mutate_at(vars(V2:V5), funs(replace(., .=="L", min(.)))) 

    V1 V2 V3 V4 V5 
1 A 4 6 5 3 
2 B 4 6 9 3 
3 C 6 7 6 5 
4 D 4 8 5 3 
相關問題