Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 指示特定值首次出现的新变量_R_Dplyr_Panel_Transformation_Hierarchical Data - Fatal编程技术网

R 指示特定值首次出现的新变量

R 指示特定值首次出现的新变量,r,dplyr,panel,transformation,hierarchical-data,R,Dplyr,Panel,Transformation,Hierarchical Data,我想创建一个新的变量,它指示变量值的第一个特定观察值 在下面的示例数据集中,我希望有一个新变量“firstna”,它是“1”,用于该播放器的第一个“NA”观察值 game_data <- data.frame(player = c(1,1,1,1,2,2,2,2), level = c(1,2,3,4,1,2,3,4), points = c(20,NA,NA,NA,20,40,NA,NA)) game_data player level points 1 1 1

我想创建一个新的变量,它指示变量值的第一个特定观察值

在下面的示例数据集中,我希望有一个新变量“firstna”,它是“1”,用于该播放器的第一个“NA”观察值

game_data <- data.frame(player = c(1,1,1,1,2,2,2,2), level = c(1,2,3,4,1,2,3,4), points = c(20,NA,NA,NA,20,40,NA,NA))

game_data
  player level points
1      1     1     20
2      1     2     NA
3      1     3     NA
4      1     4     NA
5      2     1     20
6      2     2     40
7      2     3     NA
8      2     4     NA

game\u data这是一个包含
数据的解决方案。表

library("data.table")

game_data <- data.table(player = c(1,1,1,1,2,2,2,2), level = c(1,2,3,4,1,2,3,4), points = c(20,NA,NA,NA,20,40,NA,NA))

game_data[, firstna:=is.na(points) & !is.na(shift(points)), player][]
# > game_data[, firstna:=is.na(points) & !is.na(shift(points)), player][]
#    player level points firstna
# 1:      1     1     20   FALSE
# 2:      1     2     NA    TRUE
# 3:      1     3     NA   FALSE
# 4:      1     4     NA   FALSE
# 5:      2     1     20   FALSE
# 6:      2     2     40   FALSE
# 7:      2     3     NA    TRUE
# 8:      2     4     NA   FALSE
库(“data.table”)
游戏数据游戏数据[,firstna:=is.na(点数)和!is.na(移位(点数)),玩家][]
#玩家等级分数firstna
#1:120假
#2:12不适用
#3:13 NA假
#4:14 NA错误
#5:2120假
#6:240假
#7:23不适用
#8:24NA假

您可以通过按玩家分组,然后进行变异来检查一行是否有NA值,而前一行没有

game_data %>%
  group_by(player) %>%
  mutate(firstna = ifelse(is.na(points) & lag(!is.na(points)),1,0)) %>%
  ungroup()
结果:

# A tibble: 8 x 4
# Groups:   player [2]
  player level points firstna
   <dbl> <dbl>  <dbl>   <dbl>
1      1     1     20       0
2      1     2     NA       1
3      1     3     NA       0
4      1     4     NA       0
5      2     1     20       0
6      2     2     40       0
7      2     3     NA       1
8      2     4     NA       0
#一个tible:8 x 4
#分组:玩家[2]
玩家等级分数firstna
1      1     1     20       0
2 1 2 NA 1
3 1 3 NA 0
414Na0
5      2     1     20       0
6      2     2     40       0
7 2 3 NA 1
8 2 4 NA 0
按玩家分组,然后创建一个布尔向量,用于前一行中既为NA又不重复的案例

# A tibble: 8 x 4
# Groups:   player [2]
  player level points firstna
   <dbl> <dbl>  <dbl>   <dbl>
1      1     1     20       0
2      1     2     NA       1
3      1     3     NA       0
4      1     4     NA       0
5      2     1     20       0
6      2     2     40       0
7      2     3     NA       1
8      2     4     NA       0
一直运行到玩家组末尾的NAs块的第一行:

game_data %>% 
  group_by(player) %>% 
  mutate(firstna=as.numeric(is.na(points) & !duplicated(cbind(points,cumsum(!is.na(points))))))
库(tidyverse)
库(数据表)
数据帧(
player=c(1,1,1,1,2,2,2),
级别=c(1,2,3,4,1,2,3,4),
点=c(20,NA,NA,NA,20,40,NA,NA)
)->游戏数据

游戏数据基础1A基础
R
解决方案:

ave(game_data$points, game_data$player,
    FUN = function(x) seq_along(x) == match(NA, x, nomatch = 0))

另一个
ave
选项,按组(
player
)查找第一个
NA


game_data$firstna另一种使用base的方法:

game_data$firstna <-
unlist(
tapply(game_data$points, game_data$player, function(x) {i<-which(is.na(x))[1];x[]<-0;x[i]<-1;x})
)

使用
diff

transform(game_data, firstna = ave(is.na(points), player, FUN = function(x) c(0,diff(x))))
#   player level points firstna
# 1      1     1     20       0
# 2      1     2     NA       1
# 3      1     3     NA       0
# 4      1     4     NA       0
# 5      2     1     20       0
# 6      2     2     40       0
# 7      2     3     NA       1
# 8      2     4     NA       0
及其
dplyr
等价物:

library(dplyr)
game_data %>% group_by(player) %>% mutate(firstna = c(0,diff(is.na(points))))
# # A tibble: 8 x 4
# # Groups:   player [2]
#   player level points firstna
#    <dbl> <dbl>  <dbl>   <dbl>
# 1      1     1     20       0
# 2      1     2     NA       1
# 3      1     3     NA       0
# 4      1     4     NA       0
# 5      2     1     20       0
# 6      2     2     40       0
# 7      2     3     NA       1
# 8      2     4     NA       0
库(dplyr)
游戏数据%>%由(玩家)分组%>%变异(firstna=c(0,diff(is.na(点数)))
##A tibble:8 x 4
##组别:玩家[2]
#玩家等级分数firstna
#          
# 1      1     1     20       0
#2 1 2 NA 1
#3 1 3 NA 0
#414Na0
# 5      2     1     20       0
# 6      2     2     40       0
#7 2 3 NA 1
#8 2 4 NA 0

这假设NAs总是集中在一起。伙计,
ave
再次攻击。该功能需要更好的公关。做得好!(而且速度也非常快)是啊,见鬼,这和平均数无关。。。为什么文档中会这样描述呢?一个问题:为什么返回的是数字而不是逻辑(正如我从
=
中所期望的那样)?
ave
将返回类型强制为其第一个参数的类型。因此,作为
game\u data$points
numeric
,返回一个数值向量。这是使用
ave
时要记住的一件事。这一次,该功能运行良好,但在其他情况下,它可能是一个障碍。这解释了为什么在
game_data$的情况下,分数也非常好。可能比原版稍快:)酷!但是…我认为它与前面的
NA
…:
cumsum(is.NA(c(NA,1,NA))
相违背。也许OP从未出现过这种情况,但我只是想提一提。谢谢你的帮助,代码运行得很好,我喜欢使用dplyr。如果我想在第一个“NA”出现之前的一行中有firstna的“1”(在第1行和第6行的示例代码中),我可以添加什么?我在上面的答案中添加了必要的代码。很高兴听到这有帮助。别忘了投票并接受!非常感谢,这对我帮助很大!那么,把它当作一个新问题来考虑吧。你会得到更多的关注的,不管怎样。还添加了该解决方案。
ave(game_data$points, game_data$player,
    FUN = function(x) seq_along(x) == match(NA, x, nomatch = 0))
game_data$firstna <- ave(game_data$points, game_data$player, 
                         FUN = function(x) cumsum(is.na(x)) == 1)

game_data
#  player level points firstna
#1      1     1     20       0
#2      1     2     NA       1
#3      1     3     NA       0
#4      1     4     NA       0
#5      2     1     20       0
#6      2     2     40       0
#7      2     3     NA       1
#8      2     4     NA       0
game_data$firstna <-
unlist(
tapply(game_data$points, game_data$player, function(x) {i<-which(is.na(x))[1];x[]<-0;x[i]<-1;x})
)
ave(game_data$points, game_data$player, FUN = function(x) {
    i<-which(is.na(x))[1];x[]<-0;x[i]<-1;x
})
transform(game_data, firstna = ave(is.na(points), player, FUN = function(x) c(0,diff(x))))
#   player level points firstna
# 1      1     1     20       0
# 2      1     2     NA       1
# 3      1     3     NA       0
# 4      1     4     NA       0
# 5      2     1     20       0
# 6      2     2     40       0
# 7      2     3     NA       1
# 8      2     4     NA       0
library(dplyr)
game_data %>% group_by(player) %>% mutate(firstna = c(0,diff(is.na(points))))
# # A tibble: 8 x 4
# # Groups:   player [2]
#   player level points firstna
#    <dbl> <dbl>  <dbl>   <dbl>
# 1      1     1     20       0
# 2      1     2     NA       1
# 3      1     3     NA       0
# 4      1     4     NA       0
# 5      2     1     20       0
# 6      2     2     40       0
# 7      2     3     NA       1
# 8      2     4     NA       0