Используйте только не-NA клетки, чтобы заменить ячейки в другом столбце - PullRequest
1 голос
/ 15 января 2020

долгое время слушатель, впервые звонящий, поэтому я прошу прощения, если мне не хватает важной информации в посте или вообще.

Короче говоря, у меня есть два столбца, один из которых заполнен каждой ячейкой (поведение). Другая (игра) в основном NA, за исключением нескольких ячеек, но то, что есть в каждой ячейке, не обязательно одинаково. Для каждого не-NA в игре, независимо от содержимого, я хочу использовать его для замены данных в соответствующей строке в столбце поведения.

Вот данные:

behavior<-c("run","jump","play","walk","jump","walk","run","play","jump","jump")
game<-c(NA,"tag",NA,NA,NA,"slide",NA,"tag",NA,"hopscotch")

    test<-data.frame(behavior,game)

behavior    game
1   run     NA
2   jump    tag
3   play    NA
4   walk    NA
5   jump    NA
6   walk    slide
7   run     NA
8   play    tag
9   jump    NA
10  jump    hopscotch

Я хочу, чтобы это выглядело так:

behavior    game
1   run     NA
2   tag     tag
3   play    NA
4   walk    NA
5   jump    NA
6   slide   slide
7   run     NA
8   tag     tag
9   jump    NA
10  hopscotch   hopscotch

Я пробовал писать функции, используя что-то вроде! (Test $ game == Нет) с if / else, но я думаю, что мне здесь чего-то не хватает. Это кажется довольно простым, но после изучения потока переполнения стека я получил массу советов о том, как заменить NA, но не о том, как использовать только не-NA для замены уже заполненной ячейки. Ради интереса, мне также было бы интересно узнать, есть ли способ поменять значения ячеек, поэтому второй строкой будет тег / переход, а не тег / тег. Рад предложить любую дополнительную информацию / разъяснения, и любой совет очень ценится.

Ответы [ 2 ]

2 голосов
/ 15 января 2020

Чтение ваших данных в виде строк, а не факторов

test<- data.frame(behavior,game, stringsAsFactors = FALSE)

Мы можем использовать простые ifelse с transform, где значение behavior изменяется на основе столбца NA value game ,

transform(test, behavior = ifelse(is.na(game), behavior, game))

#    behavior      game
#1        run      <NA>
#2        tag       tag
#3       play      <NA>
#4       walk      <NA>
#5       jump      <NA>
#6      slide     slide
#7        run      <NA>
#8        tag       tag
#9       jump      <NA>
#10 hopscotch hopscotch

factors внутренне хранятся в виде чисел, если вы не читаете их как символы, тогда один и тот же код выдаст

test<- data.frame(behavior,game)
transform(test, behavior = ifelse(is.na(game), behavior, game))
#   behavior      game
#1         3      <NA>
#2         3       tag
#3         2      <NA>
#4         4      <NA>
#5         1      <NA>
#6         2     slide
#7         3      <NA>
#8         3       tag
#9         1      <NA>
#10        1 hopscotch

, что очень запутанно и трудно отлаживать. В качестве альтернативы, мы можем переопределить значения коэффициента, используя as.character, что даст ожидаемый результат.

transform(test, behavior = ifelse(is.na(game), as.character(behavior), 
                                               as.character(game)))
0 голосов
/ 15 января 2020

добро пожаловать в SO.

Спасибо за предоставленные примеры данных, это действительно полезно!

Я бы лично занялся этим, используя пакет dplyr и функцию coalesce() (если вы знакомы с SQL, вы можете узнать эту функцию, если нет, не волнуйтесь!).

Функция coalecse() принимает первое не-NA значение для двух или более векторов. Вы можете использовать его самостоятельно или, по своему усмотрению, внутри функции mutate() (также из dplyr), которая полезна для создания / изменения столбцов внутри фрейма данных:

library(dplyr)

behavior<-c("run","jump","play","walk","jump","walk","run","play","jump","jump")
game<-c(NA,"tag",NA,NA,NA,"slide",NA,"tag",NA,"hopscotch")

# Make the data frame, using stringsAsFactors = FALSE to make sure our data
# get treated as characters, not factors 
test <- data.frame(behavior = behavior, game = game, stringsAsFactors = FALSE)
dplyr::mutate(
     test,
     behavior = dplyr::coalesce(game, behavior)
)

    behavior      game
1        run      <NA>
2        tag       tag
3       play      <NA>
4       walk      <NA>
5       jump      <NA>
6      slide     slide
7        run      <NA>
8        tag       tag
9       jump      <NA>
10 hopscotch hopscotch

Чтобы помочь визуализировать немного, давайте создадим новый столбец (вместо перезаписи behavior):

mutate(
     test,
     new = coalesce(game, behavior)
)

   behavior      game       new
1       run      <NA>       run
2      jump       tag       tag
3      play      <NA>      play
4      walk      <NA>      walk
5      jump      <NA>      jump
6      walk     slide     slide
7       run      <NA>       run
8      play       tag       tag
9      jump      <NA>      jump
10     jump hopscotch hopscotch

Итак, coalesce() смотрит на game, а затем behavior, если есть значение в game is использует его, если его нет, он смотрит на behavior и вместо этого использует это значение (и если бы в нем не было значения, он использовал бы NA).

Если вам нравится такой подход, я бы порекомендовал взглянуть на (отлично) книгу R for Data Science (бесплатно онлайн здесь: https://r4ds.had.co.nz/) и коллекцию пакетов tidyverse ( https://www.tidyverse.org/).

...