r语言 - 仅使用非 NA 单元格替换另一列中的单元格



长时间的听众,第一次打电话的人,所以如果我在帖子或一般情况下错过了关键信息,我深表歉意。

简而言之,我有两列,其中一列填充了每个单元格(行为(。另一个(游戏(除了几个单元格外,大部分都是 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==NA(与if/else,但我认为我在这里错过了一些基本的东西。这似乎相当简单,但在搜索堆栈溢出之后,我看到了大量关于如何替换 NA 的建议,但没有关于如何仅使用非 NA 来替换已经填充的单元格的建议。出于好奇,如果有办法交换单元格值,我也有兴趣,所以第二行将是标签/跳转而不是标签/标签。很高兴提供任何其他信息/澄清,任何建议都非常感谢。

将数据读取为字符串而不是因子

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

我们可以将简单ifelsetransform一起使用,其中behavior的值根据列NAgame更改。

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

欢迎来到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中有一个值使用它,如果没有,它会查看behavior并使用该值(如果两者都没有值,它将使用NA(。

如果你喜欢这种方法,我建议你看看(优秀的(R for Data Science书籍(在线免费:https://r4ds.had.co.nz/(和tidyverse包集合(https://www.tidyverse.org/(。

最新更新