R 比较4列值以创建新列

R 比较4列值以创建新列,r,dataframe,lapply,R,Dataframe,Lapply,我希望将非NA值保留在一行中,然后选择其中的第一个元素 将列表作为新列ncol的最终值 下面是一个我试图获取的内容和无法获取的代码的示例 跑 ID <- c(1,2,3,4) A <- c("A", "NA", "C", "R") B <- c("G", "V", "NA", "T") C <- c("NA", "NA", "NA", "Y") D <- c("U", "W", "NA", "NA") mydf <- data.frame(ID, A,

我希望将非NA值保留在一行中,然后选择其中的第一个元素 将列表作为新列ncol的最终值

下面是一个我试图获取的内容和无法获取的代码的示例 跑

ID <- c(1,2,3,4) 
A <- c("A", "NA", "C", "R")
B <- c("G", "V", "NA", "T")
C <- c("NA", "NA", "NA", "Y")
D <- c("U", "W", "NA", "NA")


mydf <- data.frame(ID, A, B, C, D, ncol)


 ID  A  B  C  D ncol
1  1  A  G NA  U    A
2  2 NA  V NA  W    V
3  3  C NA NA NA    C
4  4  R  T  Y NA    R


mycol <- c(mydf$A, mydf$B, mydf$C, mydf$D)
for (i in seq(1:nrow(mydf))){
   listcolincldata <- lapply(mycol[i],[!is.na(mycols[i])])
   print(listcolincldata)
   mydf$newcol[i] <- (as.character(listcolincldata[1]))
}
您需要对此使用apply,以便按行循环:

资料

解决方案:

#using apply is the same as lapply, but applied row wise
#na.omit will remove the NAs for each row
#then I use [2] to pick the first value after the ID column
#result is as shown in your output
mydf$ncol <- apply(mydf, 1, function(x) na.omit(x)[2])
输出:

> mydf
  ID    A    B    C    D ncol
1  1    A    G <NA>    U    A
2  2 <NA>    V <NA>    W    V
3  3    C <NA> <NA> <NA>    C
4  4    R    T    Y <NA>    R
您需要对此使用apply,以便按行循环:

资料

解决方案:

#using apply is the same as lapply, but applied row wise
#na.omit will remove the NAs for each row
#then I use [2] to pick the first value after the ID column
#result is as shown in your output
mydf$ncol <- apply(mydf, 1, function(x) na.omit(x)[2])
输出:

> mydf
  ID    A    B    C    D ncol
1  1    A    G <NA>    U    A
2  2 <NA>    V <NA>    W    V
3  3    C <NA> <NA> <NA>    C
4  4    R    T    Y <NA>    R
克里斯, 下面是两个示例解决方案。一个修改您的数据帧,用真实的NA值替换文本NAs,第二个使用NA的文本识别。通过将margin参数设置为1,两者都在数据框的行中使用apply

A <- c("A", "NA", "C", "R")
B <- c("G", "V", "NA", "T")
C <- c("NA", "NA", "NA", "Y")
D <- c("U", "W", "NA", "NA")

# First solution: convert text NA to true NA
eg1 <- data.frame(A, B, C, D, stringsAsFactors = TRUE)
eg1[eg1 == "NA"] <- NA
eg1$solution <- apply(eg1, 1, function(rw) rw[!is.na(rw)][1])
eg1

# Second solution: string recognition
eg2 <- data.frame(A, B, C, D, stringsAsFactors = TRUE)
eg2$solution <- apply(eg2, 1, function(rw) rw[rw != "NA"][1])
eg2
克里斯, 下面是两个示例解决方案。一个修改您的数据帧,用真实的NA值替换文本NAs,第二个使用NA的文本识别。通过将margin参数设置为1,两者都在数据框的行中使用apply

A <- c("A", "NA", "C", "R")
B <- c("G", "V", "NA", "T")
C <- c("NA", "NA", "NA", "Y")
D <- c("U", "W", "NA", "NA")

# First solution: convert text NA to true NA
eg1 <- data.frame(A, B, C, D, stringsAsFactors = TRUE)
eg1[eg1 == "NA"] <- NA
eg1$solution <- apply(eg1, 1, function(rw) rw[!is.na(rw)][1])
eg1

# Second solution: string recognition
eg2 <- data.frame(A, B, C, D, stringsAsFactors = TRUE)
eg2$solution <- apply(eg2, 1, function(rw) rw[rw != "NA"][1])
eg2

另一个选项是将max.col与ties.method='first'一起使用。这将获取第一个非NA值的列索引,cbind它与行索引并获取值

mydf$ncol <- mydf[cbind(1:nrow(mydf),max.col(!is.na(mydf[,-1]), 'first')+1L)]
mydf
#   ID    A    B    C    D ncol
#1  1    A    G <NA>    U    A
#2  2 <NA>    V <NA>    W    V
#3  3    C <NA> <NA> <NA>    C
#4  4    R    T    Y <NA>    R
数据
注意:我将NA创建为真正的NA,而不是字符串

另一种选择是将max.col与ties.method='first'一起使用。这将获取第一个非NA值的列索引,cbind它与行索引并获取值

mydf$ncol <- mydf[cbind(1:nrow(mydf),max.col(!is.na(mydf[,-1]), 'first')+1L)]
mydf
#   ID    A    B    C    D ncol
#1  1    A    G <NA>    U    A
#2  2 <NA>    V <NA>    W    V
#3  3    C <NA> <NA> <NA>    C
#4  4    R    T    Y <NA>    R
数据
注意:我将NA创建为真正的NA,而不是字符串

na.omit比我的rw[!is.narw][1]更节省!我担心原来的例子用文本NA代替了真实的NA。@ElizabethAB嗨Elizabeth。谢谢你的评论。事实上,OP使用了文本“NA”,但从他的代码判断,他使用的是is.NA。他的原始data.frame可能有真正的R NAs。这就是我使用na.omit的原因。否则,他应该使用你的第二种解决方案。谢谢!NA来自不均匀的合并,我在前面的循环中输入了as.character NA…这可能就是问题所在。。。。我将更改我的循环并再次尝试。我现在有了所有真实的NA&伊丽莎白和利扎德的例子都没有说。错误。Dimx必须有一个正长度我想这是我传递的四个参数。。。我带来了mycolsna.omit比我的rw[!is.narw][1]更节省!我担心原来的例子用文本NA代替了真实的NA。@ElizabethAB嗨Elizabeth。谢谢你的评论。事实上,OP使用了文本“NA”,但从他的代码判断,他使用的是is.NA。他的原始data.frame可能有真正的R NAs。这就是我使用na.omit的原因。否则,他应该使用你的第二种解决方案。谢谢!NA来自不均匀的合并,我在前面的循环中输入了as.character NA…这可能就是问题所在。。。。我将更改我的循环并再次尝试。我现在有了所有真实的NA&伊丽莎白和利扎德的例子都没有说。错误。Dimx必须有一个正长度我想这是我传递的四个参数。。。我带来了麦可尔