2016-12-05 75 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 
相关问题