用R中相邻列中的值替换NA

时间:2021-11-01 04:23:43

I want to replace the NA in the IMIAVG column with the value in the IMILEFT or IMIRIGHT column in the same row when necessary (i.e Row 1, 6, 7). I've tried multiple things but nothing seems to work. Does this need a loop? Please note errors keep coming up with atomic vectors. Thx!

我想在必要时将IMIAVG列中的NA替换为同一行中IMILEFT或IMIRIGHT列中的值(即第1,6,7行)。我尝试了很多东西但似乎没什么用。这需要循环吗?请注意错误不断出现原子矢量。谢谢!

  IMILEFT       IMIRIGHT       IMIAVG
  NA            71.15127         NA
  72.18310      72.86607      72.52458
  70.61460      68.00766      69.31113
  69.39032      69.91261      69.65146
  72.58609      72.75168      72.66888
  70.85714         NA            NA
  NA            69.88203         NA
  74.47109      73.07963      73.77536
  70.44855      71.28647      70.86751
  NA            72.33503         NA
  69.82818      70.45144      70.13981
  68.66929      69.79866      69.23397
  72.46879      71.50685      71.98782
  71.11888      71.98336      71.55112
  NA            67.86667         NA

3 个解决方案

#1


4  

If only one value is not NA amongst IMILEFT and IMIRIGHT (as in your example), just try (df is your data.frame):

如果在IMILEFT和IMIRIGHT中只有一个值不是NA(如在您的示例中),请尝试(df是您的data.frame):

indx<-is.na(df$IMIAVG)
df$IMIAVG[indx]<-rowSums(df[indx,1:2],na.rm=TRUE)

Btw, if you want to find the mean value of each row and exclude the NA values in the process, you can set the na.rm argument as TRUE in the function rowMeans. I guess that you can obtain your last column as just:

顺便说一下,如果要查找每一行的平均值并排除过程中的NA值,可以在函数rowMeans中将na.rm参数设置为TRUE。我想你可以获得你的最后一栏:

rowMeans(df[,1:2],na.rm=TRUE)

to remove the problem at its root.

从根本上删除问题。

Data

数据

df<-structure(list(IMILEFT = c(NA, 72.1831, 70.6146, 69.39032, 72.58609, 
70.85714, NA, 74.47109, 70.44855, NA, 69.82818, 68.66929, 72.46879, 
71.11888, NA), IMIRIGHT = c(71.15127, 72.86607, 68.00766, 69.91261, 
72.75168, NA, 69.88203, 73.07963, 71.28647, 72.33503, 70.45144, 
69.79866, 71.50685, 71.98336, 67.86667), IMIAVG = c(NA, 72.52458, 
69.31113, 69.65146, 72.66888, NA, NA, 73.77536, 70.86751, NA, 
70.13981, 69.23397, 71.98782, 71.55112, NA)), .Names = c("IMILEFT", 
"IMIRIGHT", "IMIAVG"), class = "data.frame", row.names = c(NA, 
-15L))

#2


1  

You could also use pmax

你也可以使用pmax

indx <- is.na(df$IMIAVG)
df$IMIAVG[indx] <- do.call(pmax, c(df[indx, 1:2], na.rm=TRUE))

Or using data.table

或者使用data.table

library(data.table) 
setDT(df)[is.na(IMIAVG), IMIAVG:=pmax(IMILEFT, IMIRIGHT, na.rm=TRUE)]

#3


0  

df <- read.table(text = "IMILEFT       IMIRIGHT       IMIAVG
  NA            71.15127         NA
  72.18310      72.86607      72.52458
  70.61460      68.00766      69.31113
  69.39032      69.91261      69.65146
  72.58609      72.75168      72.66888
  70.85714         NA            NA
  NA            69.88203         NA
  74.47109      73.07963      73.77536
  70.44855      71.28647      70.86751
  NA            72.33503         NA
  69.82818      70.45144      70.13981
  68.66929      69.79866      69.23397
  72.46879      71.50685      71.98782
  71.11888      71.98336      71.55112
  NA            67.86667         NA" , header = T)

library("dplyr")

    df %>%
  mutate(
    IMIAVG = ifelse(
                      is.na(IMIAVG) , 
                      ifelse(is.na(IMIRIGHT) ,IMILEFT ,IMIRIGHT  ) , 
                      IMIAVG
                   )
         )

#1


4  

If only one value is not NA amongst IMILEFT and IMIRIGHT (as in your example), just try (df is your data.frame):

如果在IMILEFT和IMIRIGHT中只有一个值不是NA(如在您的示例中),请尝试(df是您的data.frame):

indx<-is.na(df$IMIAVG)
df$IMIAVG[indx]<-rowSums(df[indx,1:2],na.rm=TRUE)

Btw, if you want to find the mean value of each row and exclude the NA values in the process, you can set the na.rm argument as TRUE in the function rowMeans. I guess that you can obtain your last column as just:

顺便说一下,如果要查找每一行的平均值并排除过程中的NA值,可以在函数rowMeans中将na.rm参数设置为TRUE。我想你可以获得你的最后一栏:

rowMeans(df[,1:2],na.rm=TRUE)

to remove the problem at its root.

从根本上删除问题。

Data

数据

df<-structure(list(IMILEFT = c(NA, 72.1831, 70.6146, 69.39032, 72.58609, 
70.85714, NA, 74.47109, 70.44855, NA, 69.82818, 68.66929, 72.46879, 
71.11888, NA), IMIRIGHT = c(71.15127, 72.86607, 68.00766, 69.91261, 
72.75168, NA, 69.88203, 73.07963, 71.28647, 72.33503, 70.45144, 
69.79866, 71.50685, 71.98336, 67.86667), IMIAVG = c(NA, 72.52458, 
69.31113, 69.65146, 72.66888, NA, NA, 73.77536, 70.86751, NA, 
70.13981, 69.23397, 71.98782, 71.55112, NA)), .Names = c("IMILEFT", 
"IMIRIGHT", "IMIAVG"), class = "data.frame", row.names = c(NA, 
-15L))

#2


1  

You could also use pmax

你也可以使用pmax

indx <- is.na(df$IMIAVG)
df$IMIAVG[indx] <- do.call(pmax, c(df[indx, 1:2], na.rm=TRUE))

Or using data.table

或者使用data.table

library(data.table) 
setDT(df)[is.na(IMIAVG), IMIAVG:=pmax(IMILEFT, IMIRIGHT, na.rm=TRUE)]

#3


0  

df <- read.table(text = "IMILEFT       IMIRIGHT       IMIAVG
  NA            71.15127         NA
  72.18310      72.86607      72.52458
  70.61460      68.00766      69.31113
  69.39032      69.91261      69.65146
  72.58609      72.75168      72.66888
  70.85714         NA            NA
  NA            69.88203         NA
  74.47109      73.07963      73.77536
  70.44855      71.28647      70.86751
  NA            72.33503         NA
  69.82818      70.45144      70.13981
  68.66929      69.79866      69.23397
  72.46879      71.50685      71.98782
  71.11888      71.98336      71.55112
  NA            67.86667         NA" , header = T)

library("dplyr")

    df %>%
  mutate(
    IMIAVG = ifelse(
                      is.na(IMIAVG) , 
                      ifelse(is.na(IMIRIGHT) ,IMILEFT ,IMIRIGHT  ) , 
                      IMIAVG
                   )
         )