我有一个如下所示的数据集
Account eta1 eta2 eta3 eta4 eta6 grp grp1
123 NA 0 0 1 NA pol tree
456 NA NA NA NA 1 cal tre
789 NA NA NA 0 2 pal tre
111 NA NA NA NA NA trol tre
我希望我的输出看起来像这样
ACC eta grp grp1
123 1 pol tree
456 1 cal tre
789 2 pal tre
111 NA trol tre
我如何使用R实现这一目标
答案 0 :(得分:4)
尝试一下:
df<-structure(list(Account = c(123L, 456L, 789L, 111L), eta1 = c(NA,
NA, NA, NA), eta2 = c(0L, NA, NA, NA), eta3 = c(0L, NA, NA, NA
), eta4 = c(1L, NA, 0L, NA), eta6 = c(NA, 1L, 2L, NA), grp = c("pol",
"cal", "pal", "trol"), grp1 = c("tree", "tre", "tre", "tre")), class = "data.frame", row.names = c(NA,
-4L))
数据
.example {
width: 400px;
height: 90vh;
background-color: red;
border: 1px solid black;
}
答案 1 :(得分:2)
另一种方法是使用dplyr
:
library(dplyr)
df <- data.frame(stringsAsFactors = FALSE,
Account = c(123, 456, 789, 111),
eta1 = c(NA, NA, NA, NA),
eta2 = c(0, NA, NA, NA),
eta3 = c(0, NA, NA, NA),
eta4 = c(1, NA, 0, NA),
eta6 = c(NA, 1, 2, NA),
grp = c("pol", "cal", "pal", "trol"),
grp1 = c("tree", "tre", "tre", "tre"))
df %>%
mutate(eta = pmax(eta1, eta2, eta3, eta4, eta6, na.rm = TRUE)) %>%
select(Account, eta, grp, grp1)
答案 2 :(得分:0)
在数字列上应用max
,但有例外规则。 (但是 @nicola 的解决方案更好。)
apply(dat[sapply(dat, is.numeric)], 1,
function(x) if (all(is.na(x))) NA else max(na.omit(x)))
# [1] 2 1 2 NA
您可以将其进一步包装到自定义函数中
row.max <- function(dat) {
return(apply(dat[sapply(dat, is.numeric)], 1,
function(x) if (all(is.na(x))) NA else max(na.omit(x))))
}
用法:
dat <- transform(dat, max=row.max(dat))
# Account eta1 eta2 eta3 eta4 eta6 grp grp1 max
# 1 123 NA 1 1 2 NA pol tree 2
# 2 456 NA NA NA NA 1 cal tre 1
# 3 789 NA NA NA 1 2 pal tre 2
# 4 111 NA NA NA NA NA trol tre NA
数据
dat <- structure(list(Account = structure(c(2L, 3L, 4L, 1L), .Label = c("111",
"123", "456", "789", "Account"), class = "factor"), eta1 = c(NA_real_,
NA_real_, NA_real_, NA_real_), eta2 = c(1, NA, NA, NA), eta3 = c(1,
NA, NA, NA), eta4 = c(2, NA, 1, NA), eta6 = c(NA, 1, 2, NA),
grp = structure(c(4L, 1L, 3L, 5L), .Label = c("cal", "grp",
"pal", "pol", "trol"), class = "factor"), grp1 = structure(c(3L,
2L, 2L, 2L), .Label = c("grp1", "tre", "tree"), class = "factor")), row.names = c(NA,
-4L), class = "data.frame")
答案 3 :(得分:0)
我喜欢使用dplyr
和tidyr
处理类似的问题,特别是将数据重塑为可扩展的形式。通常,我更喜欢将ETA变量放在一列中,而不是在eta1
,eta2
等上进行操作,因此我不会遗漏任何东西,因此我的工作足够灵活以添加或删除列。
就像其他人提到的那样,棘手的部分即使在所有值均为NA
的情况下也获得了最大值。我编写了一个函数来处理此问题,如果所有值均为NA
,则返回NA
。
library(dplyr)
library(tidyr)
max_or_na <- function(x) {
if (all(is.na(x))) {
NA
} else {
max(x, na.rm = T)
}
}
df %>%
gather(key = eta, value, starts_with("eta")) %>%
group_by(Account, grp, grp1) %>%
summarise(eta = max_or_na(value))
#> # A tibble: 4 x 4
#> # Groups: Account, grp [4]
#> Account grp grp1 eta
#> <int> <chr> <chr> <int>
#> 1 111 trol tre NA
#> 2 123 pol tree 1
#> 3 456 cal tre 1
#> 4 789 pal tre 2
然后,您可以根据需要取消分组和重新排序。