如果任何其他是NA,则设置新变量NA

SDa*_*ahm 4 r

我想在我的数据框中添加一个新变量(N_notNAs),它定义是否有任何其他变量是NA.

x   y   z   N_notNAs
2   3   NA  NA
NA  1   3   NA
2   3   5   1
4   4   3   1
Run Code Online (Sandbox Code Playgroud)

Dav*_*urg 11

不知道为什么这是你想要的输出,但实现这一目标的一种可能方法是将NA每行相加并加上它的功效NA- 这样NA ^ 0将返回1,其他一切都将变为NA

NA^rowSums(is.na(df))
# [1] NA NA  1  1
Run Code Online (Sandbox Code Playgroud)


G. *_*eck 6

@David Arenburg的解决方案非常漂亮但不管怎么说还有一些.

前4个假设列df是数字并使用相同的基本思想,而后3个不需要数字列.他们也使用一个共同的想法.

该ifelse解决方案在字符数方面最长,但可能更具可读性且最不棘手.

正如下面的@alexis_laz所提到的,apply(...)可以!complete.cases(df)在最后3个解决方案中替换,并且我们会得到一些简化ifelse(complete.cases(df), 1, NA),c(NA, 1)[complete.cases(df) + 1]并且match(complete.cases(df), TRUE).

rowSums(0*df) + 1

max.col(0*df) + 1

do.call(pmin, 0*df) + 1

do.call(pmax, 0*df) + 1

ifelse(apply(df, 1, anyNA), NA, 1)

c(NA, 1)[apply(df, 1, anyNA) + 1]

match(apply(df, 1, anyNA), FALSE)
Run Code Online (Sandbox Code Playgroud)

有一些问题为什么你想要一个NA或1的列.如果你想要一个逻辑TRUE/FALSE结果那么apply(df, 1, anyNA)就可以了.

  • 添加到集合中,`!complete.cases(df)`可以很方便地创建输出. (8认同)

Ten*_*bai 5

免责声明:此处基准测试的一些答案产生TRUE/FALSE向量和NOT NA或1向量.

为了便于获取信息,这里是我的机器上的基准测试,用于3列data.frame,包含1e6行:

Unit: milliseconds
               expr        min         lq       mean     median         uq        max neval    cld
     alexis_laz(df)   12.87138   13.30044   15.46142   13.49258   13.80019   29.59228    10 a     
          akrun(df)   46.06203   48.31564   49.82198   49.94947   51.05219   53.91161    10 ab    
 GGrothendieck3(df)   55.42513   56.59798   69.37274   59.16803   64.44442  155.62797    10 ab    
 GGrothendieck4(df)   54.88489   58.08043   69.54111   58.63820   65.36838  149.21380    10 ab    
 GGrothendieck2(df)   60.26961   62.37184   97.93301   69.80034  158.39302  193.03562    10  bc   
          By989(df)  115.30531  118.81843  133.44343  123.17356  130.36815  223.22601    10   c   
 GGrothendieck1(df)  123.99504  128.61030  140.62055  132.31073  137.83856  220.33666    10   c   
          David(df)  131.42639  131.66415  143.03384  133.50082  136.29453  225.17487    10   c   
 GGrothendieck7(df) 1100.69319 1109.60500 1147.25668 1142.83955 1156.37090 1270.32547    10    d  
 GGrothendieck6(df) 1060.97719 1124.85486 1148.54833 1140.91949 1170.62952 1247.80220    10    d  
 GGrothendieck5(df) 1218.79235 1251.03109 1287.47851 1285.20543 1311.82753 1364.89158    10     e 
   PaulHiemstra(df) 1436.31149 1461.14340 1511.42476 1502.34413 1552.09517 1608.22418    10      f
Run Code Online (Sandbox Code Playgroud)

对于具有1e3行的1e5列的df:

Unit: milliseconds
               expr        min         lq       mean     median         uq        max neval  cld
     alexis_laz(df)   356.1987   360.8647   366.2464   364.4488   368.9666   391.5828    10 a   
          David(df)  1387.1657  1415.7325  1530.0748  1436.9192  1542.1830  1968.9455    10 a   
          akrun(df)  1773.5728  1800.9288  1880.9201  1868.3143  1965.7862  2018.0870    10 a   
 GGrothendieck5(df)  4891.3247  5385.9903  8206.9116  9065.2893  9890.5795 10284.7369    10  b  
 GGrothendieck6(df)  5034.4408  9089.9334  9099.5746  9785.7042 10221.1537 11905.3997    10  b  
 GGrothendieck7(df)  5142.7372  9635.2558  9711.4691  9861.5164 10524.7317 11651.6198    10  b  
   PaulHiemstra(df)  5326.8807  9959.3951 10079.1672 10175.4814 11048.6218 12659.1130    10  b  
          By989(df)  9941.5236 10015.6652 10090.2076 10067.7127 10123.5885 10300.4110    10  b  
 GGrothendieck2(df) 25715.5451 25840.3138 26686.3386 26453.6770 26982.5627 29689.6019    10   c 
 GGrothendieck3(df) 26065.7005 26343.5734 27112.4387 26470.7166 27267.7166 31374.5133    10   c 
 GGrothendieck4(df) 25911.6476 26179.3999 27121.3442 26361.2242 27335.2762 31941.6339    10   c 
 GGrothendieck1(df) 34979.3212 35162.3589 36254.1681 35685.4975 36470.3027 41130.0531    10    d
Run Code Online (Sandbox Code Playgroud)

源代码:

David <-function(df) {
  NA^rowSums(is.na(df))
}

By989 <- function(df) {
  rowSums(df) & rowSums(df, na.rm = T)
}

PaulHiemstra <- function(df) {
  ifelse(apply(is.na(df), 1, any), NA, 1)
}

akrun <- function(df) {
  NA^Reduce(`|`, lapply(df, is.na))
}

GGrothendieck1 <- function(df) {
  rowSums(0*df) + 1
}

GGrothendieck2 <- function(df) {
  max.col(0*df) + 1
}

GGrothendieck3 <- function(df) {
  do.call(pmin, 0*df) + 1
}

GGrothendieck4 <- function(df) {
  do.call(pmax, 0*df) + 1
}

GGrothendieck5 <- function(df) {
  ifelse(apply(df, 1, anyNA), NA, 1)
}

GGrothendieck6 <- function(df) {
  c(NA, 1)[apply(df, 1, anyNA) + 1]
}

GGrothendieck7 <- function(df) {
  match(apply(df, 1, anyNA), FALSE)
}

alexis_laz <- function(df) {
  complete.cases(df)
}

set.seed(5)
n<-function(x) sample(c(1:5,NA),1e6,replace=TRUE) 
df<-data.frame(A=n(),B=n(),C=n())
results<-microbenchmark(David(df),
               By989(df),
               PaulHiemstra(df),
               akrun(df),
               GGrothendieck1(df),
               GGrothendieck2(df),
               GGrothendieck3(df),
               GGrothendieck4(df),
               GGrothendieck5(df),
               GGrothendieck6(df),
               GGrothendieck7(df),
               alexis_laz(df),
               times=10)
print(results,order="mean")
Run Code Online (Sandbox Code Playgroud)

  • @ 989你是NineHeightNine ;-) (3认同)
  • @ 989数字作为函数名称很难,我会​​更正拼写:p(使用更多列进行更好的基准测试) (3认同)
  • 我想,除了替代方案之外,另一种让`complete.cases`工作的方法是`replace(NA_integer_,complete.cases(df),1L)`,如果不是 - 就是``{ans = rep_len(NA_integer_,nrow( DF)); ans [complete.cases(df)] = 1L; ans}`以避免一些强制和操作. (3认同)
  • 很高兴看到这些统计数据,谢谢@Tensibai! (2认同)