我有一个海洋数据的df,CTD转换/站名在一列,深度在另一列。看上去像这样
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"))我使用聚合()来查找每个min/max,并尝试了ifelse()和for循环来替换值,但无法使其工作。帮助是非常感谢的。大卫
发布于 2016-02-17 12:20:25
下面是一种典型的拆分/应用/组合方法。但是,您应该知道,通过在数字列中引入字符串,整个列将转换为字符。
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发布于 2016-02-17 13:11:19
如果每个“强制转换”只有一个最小/最大值,则另一个选项是使用data.table。将“data.frame”转换为“data.table”(setDT(is)),按“强制”分组,我们将“深度”组合成“深度”,并将“面”连接到“深度”的元素(最后一个除外),然后是‘底部’,从而创建新的列。
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]发布于 2016-02-17 13:41:35
您也可以使用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弟子所述。
https://stackoverflow.com/questions/35456318
复制相似问题