r - 如何使用 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
我需要数据框列名称为df1
7 到 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”并不重要。
谢谢!
解决方案
你可以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)
推荐阅读
- c# - 如何在 Xamarin.forms 中制作没有标题的选项卡栏
- powershell - Get-UnifiedGroup 和 Get-Teams:如何在 powershell 中制作脚本并将其导出到 csv 文件
- typescript - 强制因变量类型的最佳/正确模式
- debugging - 即使调试器工作正常,bochs 也会不断崩溃
- flutter - 当我在提示符中输入颤振命令时,它会立即关闭
- android - 在 react-native+android 中阻止具有特定时间和日期的应用程序
- node.js - 将文件从 Express.js 和 Multer 上传到持久 Docker Volume
- sql - 当语句包含列表中的项目时,将其显示在新列中
- batch-file - 有没有办法通过批处理脚本在某些条件下将文件保存在两个不同的文件夹中
- c++ - C++模板类型参数的自动推导