2016-02-17 58 views
0

我有一个df的海洋学数据,其中一列中的CTD演员/电台名称和另一列中的深度。它看起来是这样的查找最小值并用r中的字符串替换

is <- data.frame(cast=c("a","a","a","b","b","b"), depth=c(10,20,30,5,15,25)) 

现在我想找到每个投最小和最大深度和替换“表面”和“底部”的值,分别。结果应该是这样的:

want <- data.frame(cast=c("a","a","a","b","b","b"), depth=c("surface",20,"bottom","surface",15,"bottom")) 

我用骨料()来找到每个最小值/最大值,并试图ifelse()与循环替换值,但不能使它工作。 非常感谢帮助。 大卫

回答

1

这是一个经典的拆分/应用/组合方法。但是,您应该知道,通过在数字列中引入字符串,整列将转换为字符。

do.call(rbind, lapply(split(is, is$cast), transform, depth = 
ifelse(depth == min(depth), "surface", ifelse(depth == max(depth), "bottom", depth)))) 
# cast depth 
#a.1 a surface 
#a.2 a  20 
#a.3 a bottom 
#b.4 b surface 
#b.5 b  15 
#b.6 b bottom 

为了避免类型转换,你可以考虑不同的方法,例如:

do.call(rbind, lapply(split(is, is$cast), transform, 
      surface = depth == min(depth), 
      bottom = depth == max(depth))) 
# cast depth surface bottom 
#a.1 a 10 TRUE FALSE 
#a.2 a 20 FALSE FALSE 
#a.3 a 30 FALSE TRUE 
#b.4 b  5 TRUE FALSE 
#b.5 b 15 FALSE FALSE 
#b.6 b 25 FALSE TRUE 
+0

Thanx @docendo discimus。这工作。我对转换为字符没有问题。无论如何,通过粘贴投影和深度,每个样本都有一个唯一的标识符。 但是你能解释一下,这里有什么“变换”? –

1

如果只有一个最小值/最大值每“投”,另一种选择是使用data.table值。将'data.frame'转换为'data.table'(setDT(is)),按照'cast'分组,我们order'深度',并通过将'surface'连接到'depth'的元素来创建新列一个,然后是“底部”。

library(data.table) 
setDT(is)[order(depth), depth1 := c('surface', 
         depth[2:(.N-1)], 'bottom') ,cast] 
is 
# cast depth depth1 
#1: a 10 surface 
#2: a 20  20 
#3: a 30 bottom 
#4: b  5 surface 
#5: b 15  15 
#6: b 25 bottom 

如果存在这种情况只存在于“投”

setDT(is)[order(depth), depth1 := if(.N > 1) 
    c('surface', depth[2:(.N-1)], 'bottom') else depth ,cast] 
0

使用by类似的方法单一的观察。

# First cbind an index 
is$index <- 1:nrow(is) 

# then find the max and min and return the indeces 
foo <- function(x) cbind(min= x$index[which.min(x$depth)], max= x$index[which.max(x$depth)]) 
gr <- do.call(rbind, by(is, list(is$cast), FUN= foo)) 

# subset the extremes and replace the values with your choice. 
is[gr[,1], "depth"] <- "surface" 
is[gr[,2], "depth"] <- "bottom" 
1

您还可以使用tapply

newdepth <- c(is$cast,is$depth) 
newdepth[is==tapply(is$depth,is$cast,max)] <- "bottom" 
newdepth[is==tapply(is$depth,is$cast,min)] <- "surface" 

want <- is 
want$depth <- newdepth[-(1:nrow(want))] 

但要注意字符值在want$depth作为@docendo discimus说。

相关问题