首页 > 解决方案 > 如何使用 apply 或 map 根据另一个给出的范围和内容来更改数据框的内容,特别是在范围重叠的情况下

问题描述

我最近问了以下问题。基本上我想根据另一个数据框给出的范围来修改数据框。让我们df2认为df2 <- data.frame(b=c(7,25,31,44),e=c(11,27,36,48),n=c('a','b','c','d'))导致

   b  e n
1  7 11 a
2 25 27 b
3 31 36 c
4 44 48 d

我需要数据框列名称为df17 到 11 之间的“a”,15 到 27 之间的“b”等等。我决定创建一个包含需要更改的位置的逻辑向量,在上一个问题中Ronak Shah 帮助我

logint <- rep(FALSE,50)
logint[unlist(Map(`:`, df$b, df$e))] <- TRUE

然后我开始创建一个具有足够长度的重复字母的向量

nam <- unlist(apply(df2[,c('b','e','n')],1, function(x){return(rep(x['n'],as.numeric(x['e'])-as.numeric(x['b'])+1))}))

然后我用它在 df1 中设置正确的值

df1 <- data.frame(pos=rep(0,50),name=NA)
df1[logint,'pos'] <- 1
df1[logint,'name'] <- nam

这很好,直到 的列中有重叠df2,比如说

df2 <- data.frame(b=c(7,25,31,44),e=c(11,27,46,48),n=c('a','b','c','d'))

在这种情况下, nam 向量变得太长。我怎样才能做到这一点?出于实际原因,在这种情况下,将元素 44 到 46 命名为“c”还是“d”并不重要。

谢谢!

标签: rdictionaryapply

解决方案


你可以mapply这样的地图:

df2 <- data.frame(b = c(7, 25, 31, 44), e = c(11, 27, 46, 48), n = c('a', 'b', 'c', 'd'))
logint <- rep(FALSE, 50)
newcol <- character(max(df2$e))
mapply(function(x, y) {newcol[x] <<- as.character(y)}, Map(`:`, df2$b, df2$e), df2$n)
#> [1] "a" "b" "c" "d"
newcol
#>  [1] ""  ""  ""  ""  ""  ""  "a" "a" "a" "a" "a" ""  ""  ""  ""  ""  ""  ""  "" 
#> [20] ""  ""  ""  ""  ""  "b" "b" "b" ""  ""  ""  "c" "c" "c" "c" "c" "c" "c" "c"
#> [39] "c" "c" "c" "c" "c" "d" "d" "d" "d" "d"

在这种情况下,后面的条目会覆盖前面的条目。

reprex 包于 2020-02-27 创建(v0.3.0)


推荐阅读