从数据框中筛选出非 NA 条目,同时保留只有 NA 的行
sieve out non-NA entries from data frame while retaining rows with only NA
我正在寻找一种更有效的方法(就代码长度而言)将 data.frame
从:
# V1 V2 V3 V4 V5 V6 V7 V8 V9
# 1 1 2 3 NA NA NA NA NA NA
# 2 NA NA NA 3 2 1 NA NA NA
# 3 NA NA NA NA NA NA NA NA NA
# 4 NA NA NA NA NA NA NA NA NA
# 5 NA NA NA NA NA NA 1 2 3
到
# [,1] [,2] [,3]
#[1,] 1 2 3
#[2,] 3 2 1
#[3,] NA NA NA
#[4,] NA NA NA
#[5,] 1 2 3
也就是说,我想删除多余的 NA 但正确表示只有 NA 的行。
我写了下面的函数来完成这项工作,但我确信有一个不太冗长的方法来实现同样的目标。
#Dummy data.frame
data <- matrix(c(1:3, rep(NA, 6),
rep(NA, 3), 3:1, rep(NA, 3),
rep(NA, 9),
rep(NA, 9),
rep(NA, 6), 1:3),
byrow=TRUE, ncol=9)
data <- as.data.frame(data)
sieve <- function(data) {
#get a list of all entries that are not NA
cond <- apply(data, 1, function(x) x[!is.na(x)])
#set integer(0) equal to NA
cond[sapply(cond, function(x) length(x)==0)] <- NA
#check how many items there are in non-empty rows
#(rows are either empty or contain the same number of items)
n <- max(sapply(cond, length))
#replace single NA with n NAs, where n = number of items
#first get an index of entries with single NAs
index <- (1:length(cond)) [sapply(cond, function(x) length(x)==1)]
#then replace each entry with n NAs
for (i in index) cond[[i]] <- rep(NA, n)
#turn list into a data.frame
cond <- matrix(unlist(cond), nrow=length(cond), byrow=TRUE)
cond
}
sieve(data)
我的问题类似于 关于提取分配给参与者的条件(我收到了很好的答案)。我尝试将这些答案扩展到当前的虚拟数据,但到目前为止没有成功。因此我的自定义函数相当冗长。
编辑:关于为什么我问这个问题的附加信息:第一个数据框表示实验的原始输出,在该实验中,我将参与者分配到三个条件之一(为简单起见,此处使用 3)。在每种情况下,参与者阅读不同的场景,然后回答关于他们阅读的场景的相同问题。 Qualtrics 在 V1
至 V3
列中记录了参与者在第一种情况下的回答,在 V4
至 V6
列中记录了参与者在第二种情况下的回答,以及参与者在V7
至 V9
列中的第三个条件。 (如果这组问题包含 4 个问题,则第一个条件下的参与者的答案将是 V1
到 V4
列,第一个条件下参与者的答案将是 V2
到 V8
列第二种情况的参与者......)。
如果非 NA 的长度在未完全填充 NA 的行中始终相同,您可以尝试此操作:
首先,创建一个具有适当(转置)维度的数据框,并用 NA 填充它。
d2 <- data.frame(
matrix(nrow = max(apply(d, 1, function(ii) sum(!is.na(ii)))),
ncol=nrow(d)))
然后,使用 apply
填充该数据框,然后转置它以获得您想要的结果:
d2[] <- apply(d, 1, function(ii) ii[!is.na(ii)])
t(d2)
# [,1] [,2] [,3]
#X1 1 2 3
#X2 3 2 1
#X3 NA NA NA
#X4 NA NA NA
#X5 1 2 3
我正在寻找一种更有效的方法(就代码长度而言)将 data.frame
从:
# V1 V2 V3 V4 V5 V6 V7 V8 V9
# 1 1 2 3 NA NA NA NA NA NA
# 2 NA NA NA 3 2 1 NA NA NA
# 3 NA NA NA NA NA NA NA NA NA
# 4 NA NA NA NA NA NA NA NA NA
# 5 NA NA NA NA NA NA 1 2 3
到
# [,1] [,2] [,3]
#[1,] 1 2 3
#[2,] 3 2 1
#[3,] NA NA NA
#[4,] NA NA NA
#[5,] 1 2 3
也就是说,我想删除多余的 NA 但正确表示只有 NA 的行。
我写了下面的函数来完成这项工作,但我确信有一个不太冗长的方法来实现同样的目标。
#Dummy data.frame
data <- matrix(c(1:3, rep(NA, 6),
rep(NA, 3), 3:1, rep(NA, 3),
rep(NA, 9),
rep(NA, 9),
rep(NA, 6), 1:3),
byrow=TRUE, ncol=9)
data <- as.data.frame(data)
sieve <- function(data) {
#get a list of all entries that are not NA
cond <- apply(data, 1, function(x) x[!is.na(x)])
#set integer(0) equal to NA
cond[sapply(cond, function(x) length(x)==0)] <- NA
#check how many items there are in non-empty rows
#(rows are either empty or contain the same number of items)
n <- max(sapply(cond, length))
#replace single NA with n NAs, where n = number of items
#first get an index of entries with single NAs
index <- (1:length(cond)) [sapply(cond, function(x) length(x)==1)]
#then replace each entry with n NAs
for (i in index) cond[[i]] <- rep(NA, n)
#turn list into a data.frame
cond <- matrix(unlist(cond), nrow=length(cond), byrow=TRUE)
cond
}
sieve(data)
我的问题类似于
编辑:关于为什么我问这个问题的附加信息:第一个数据框表示实验的原始输出,在该实验中,我将参与者分配到三个条件之一(为简单起见,此处使用 3)。在每种情况下,参与者阅读不同的场景,然后回答关于他们阅读的场景的相同问题。 Qualtrics 在 V1
至 V3
列中记录了参与者在第一种情况下的回答,在 V4
至 V6
列中记录了参与者在第二种情况下的回答,以及参与者在V7
至 V9
列中的第三个条件。 (如果这组问题包含 4 个问题,则第一个条件下的参与者的答案将是 V1
到 V4
列,第一个条件下参与者的答案将是 V2
到 V8
列第二种情况的参与者......)。
如果非 NA 的长度在未完全填充 NA 的行中始终相同,您可以尝试此操作:
首先,创建一个具有适当(转置)维度的数据框,并用 NA 填充它。
d2 <- data.frame(
matrix(nrow = max(apply(d, 1, function(ii) sum(!is.na(ii)))),
ncol=nrow(d)))
然后,使用 apply
填充该数据框,然后转置它以获得您想要的结果:
d2[] <- apply(d, 1, function(ii) ii[!is.na(ii)])
t(d2)
# [,1] [,2] [,3]
#X1 1 2 3
#X2 3 2 1
#X3 NA NA NA
#X4 NA NA NA
#X5 1 2 3