R:当列发生变化时,为数据帧行应用like函数

R:当列发生变化时,为数据帧行应用like函数,r,dataframe,apply,R,Dataframe,Apply,我有一个稀疏的数据帧示例。它有五个数据列,但每行只有两个条目,随机分布在各列中: id a b c d e 1 NA 10 NA NA 1 2 6 NA 10 NA NA 3 3 NA NA 2 NA 4 NA NA 9 4 NA 5 NA NA 1 NA 5 我想返回一个只有两列数据的数据帧,每行中的值: id val1 val2 1 10 1 2 6 10 3

我有一个稀疏的数据帧
示例
。它有五个数据列,但每行只有两个条目,随机分布在各列中:

id  a   b   c   d   e
1   NA  10  NA  NA  1
2   6   NA  10  NA  NA
3   3   NA  NA  2   NA
4   NA  NA  9   4   NA
5   NA  NA  1   NA  5
我想返回一个只有两列数据的数据帧,每行中的值:

id  val1    val2
1   10      1
2   6       10
3   3       2
4   9       4
5   1       5
这可以通过
for
循环实现。但是我的实际数据非常大,所以我想做一个类似于
的apply
-like函数。我所看到的一切都假设您知道将使用哪些列。我尝试创建自己的单行函数,然后使用
apply
,但不断出现错误“维数不正确”。

试试看

d1 <- setNames(data.frame(example$id,t(apply(example[-1], 1,
                        function(x) x[!is.na(x)]))),
                                 c('id', 'val1', 'val2'))
d1
#  id val1 val2
#1  1   10    1
#2  2    6   10
#3  3    3    2
#4  4    9    4
#5  5    1    5
数据
示例这应该是一种非常快速的方法:

temp <- t(example[-1])  # Matrix of all columns other than the first, transposed
cbind(example[1],       # Bind the first column with a two-column matrix
                        # created by using is.na and which
      matrix(temp[which(!is.na(temp), arr.ind = TRUE)], 
             ncol = 2, byrow = TRUE))
#   id  1  2
# 1  1 10  1
# 2  2  6 10
# 3  3  3  2
# 4  4  9  4
# 5  5  1  5

temp没有外部库,完全矢量化<代码>t(应用(例如,1,函数(x)x[!is.na(x)])
example <- structure(list(id = 1:5, a = c(NA, 6L, 3L, NA, NA),
b = c(10L, 
NA, NA, NA, NA), c = c(NA, 10L, NA, 9L, 1L), d = c(NA, NA, 2L, 
4L, NA), e = c(1L, NA, NA, NA, 5L)), .Names = c("id", "a", "b", 
"c", "d", "e"), class = "data.frame", row.names = c(NA, -5L))
temp <- t(example[-1])  # Matrix of all columns other than the first, transposed
cbind(example[1],       # Bind the first column with a two-column matrix
                        # created by using is.na and which
      matrix(temp[which(!is.na(temp), arr.ind = TRUE)], 
             ncol = 2, byrow = TRUE))
#   id  1  2
# 1  1 10  1
# 2  2  6 10
# 3  3  3  2
# 4  4  9  4
# 5  5  1  5