如何lappy!is.na()用于赋值R data.table

问题描述 投票:2回答:1

目标是在行中的最后一个值之后用“ - ”填充NA

# Like this
   SOURCE  X__2  X__3 X__4 X__5 X__6 X__7  X__8  X__9 INFO
1: 04.xlsx David David    -    -    -    -     -     -    A
2: 05.xlsx  <NA>  <NA>  Tom  Tom    -    -     -     -    B
3: 06.xlsx  <NA>  <NA> <NA> <NA> Mary Mary     -     -    C
4: 07.xlsx  <NA>  <NA> <NA> <NA> <NA> <NA> Peter Peter    D

# Sample data
dt <- data.table(SOURCE = c("04.xlsx","05.xlsx","06.xlsx","07.xlsx"),
                   X__2 = c("David",NA,NA,NA),
                   X__3 = c("David",NA,NA,NA),
                   X__4 = c(NA,"Tom",NA,NA),
                   X__5 = c(NA,"Tom",NA,NA),
                   X__6 = c(NA,NA,"Mary",NA),
                   X__7 = c(NA,NA,"Mary",NA),
                   X__8 = c(NA,NA,NA,"Peter"),
                   X__9 = c(NA,NA,NA,"Peter"),
                   INFO = LETTERS[1:4])

我的尝试但不起作用

# Find odd columns 
TAR_COL <- grep("X__",colnames(dt))[!c(TRUE,FALSE)]

dt[!is.na(TAR_COL),(TAR_COL):="-",.SDcols =TAR_COL]

此脚本在指定col时有效,但无法动态选择列

#
dt[!is.na(X__3),(grep("X__3",names(dt))+1):(grep("INFO",names(dt))-1) := "-"][]

  SOURCE  X__2  X__3 X__4 X__5 X__6 X__7  X__8  X__9 INFO
1: 04.xlsx David David    -    -    -    -     -     -    A

由于从不同的xlsx数据导入真实数据集,因此必须动态选择奇数

有没有方法在矢量化列索引中应用!is.na()并赋值?

r data.table lapply na
1个回答
4
投票

我们可以使用set。循环遍历'TAR_COL'的列索引,使用set,指定列索引(j)和行索引(i - NA在该特定列中),并将value设置为' - '

for(j in TAR_COL) set(dt, i = which(is.na(dt[[j]])), j= j, value = "-")
dt
#   SOURCE  X__2  X__3 X__4 X__5 X__6 X__7  X__8  X__9 INFO
#1: 04.xlsx David David <NA>    - <NA>    -  <NA>     -    A
#2: 05.xlsx  <NA>     -  Tom  Tom <NA>    -  <NA>     -    B
#3: 06.xlsx  <NA>     - <NA>    - Mary Mary  <NA>     -    C
#4: 07.xlsx  <NA>     - <NA>    - <NA>    - Peter Peter    D

这里,第3,5,7,9列的NA元素被替换为-


注意:!is.na(TAR_COL)没有帮助,因为'TAR_COL'只是一个列索引

Update

基于OP的澄清,即替换NA必须水平从最后出现的值到“INFO”之前的最后一列,我们可以创建一个累积和的索引,如评论中建议的@markus

# get the column names that start with 'X__'
nms <- names(dt)[startsWith(names(dt), "X__")]
# change the i index with cumulative sum
for(j in nms) set(dt, i = which(cumsum(!is.na(dt[[j]])) == 0), j = j, value = "-") 
© www.soinside.com 2019 - 2024. All rights reserved.