Как использовать apply или map для изменения содержимого фрейма данных на основе диапазона и содержимого, заданного другим, особенно если диапазоны перекрывают друг друга - PullRequest
0 голосов
/ 27 февраля 2020

Я недавно задал следующий вопрос . По сути, я хотел изменить фрейм данных на основе диапазонов, заданных другим. давайте возьмем 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 было «a» между 7 и 11, «b» между 15 и 27 и т. д. , Я решил создать логический вектор с позициями, которые нуждались в изменении, и в предыдущем вопросе Ронак Шах помог мне с

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'))

В этом случае вектор имени становится слишком длинным. Как я могу это сделать? По практическим соображениям не имеет значения, называются ли элементы 44–46 в этом случае «c» или «d».

Спасибо!

1 Ответ

1 голос
/ 27 февраля 2020

Вы можете 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"

Более поздние записи перезаписывают более ранние записи в этом случае.

Создано в 2020-02-27 с помощью представительный пакет (v0.3.0)

...