我有一个data.frame dt
,其中包含一些重复的密钥和缺少的数据,即
Name Height Weight Age
Alice 180 NA 35
Bob NA 80 27
Alice NA 70 NA
Charles 170 75 NA
在这种情况下,键是名称,我想在每列中应用类似
的函数f <- function(x){
x <- x[!is.na(x)]
x <- x[1]
return(x)
}
在按密钥聚合时(即“名称”列),以便获得结果
Name Height Weight Age
Alice 180 70 35
Bob NA 80 27
Charles 170 75 NA
我试过
dt_agg <- aggregate(. ~ Name,
data = dt,
FUN = f)
我遇到了一些错误,然后我尝试了以下
dt_agg_1 <- aggregate(Height ~ Name,
data = dt,
FUN = f)
dt_agg_2 <- aggregate(Weight ~ Name,
data = dt,
FUN = f)
这次它起作用了。
由于我有50列,第二种方法对我来说非常麻烦。有没有办法解决第一种方法?
感谢您的帮助!
答案 0 :(得分:3)
您与aggregate
函数非常接近,您需要调整聚合处理NA
的方式(从na.omit
到na.pass
)。我的猜测是聚合首先删除NA的所有行,然后进行聚合,而不是删除NAs,因为聚合迭代要聚合的列。由于您的示例数据帧在每行中都有NA
,因此您最终会得到一个0行数据帧(这是我在运行代码时遇到的错误)。我通过删除除了一个NA以外的所有NA来测试它,并且您的代码按原样运行。因此,我们设置na.action = na.pass
以通过NA。
dt_agg <- aggregate(. ~ Name,
data = dt,
FUN = f, na.action = "na.pass")
dt_agg <- aggregate(dt[, -1],
by = list(dt$Name),
FUN = f)
dt_agg
# Group.1 Height Weight Age
# 1 Alice 180 70 35
# 2 Bob NA 80 27
# 3 Charles 170 75 NA
答案 1 :(得分:2)
您可以使用dplyr
:
library(dplyr)
df %>%
group_by(Name) %>%
summarize_all(funs(sort(.)[1]))
<强>结果:强>
# A tibble: 3 x 4
Name Height Weight Age
<fctr> <int> <int> <int>
1 Alice 180 70 35
2 Bob NA 80 27
3 Charles 170 75 NA
数据:强>
df = read.table(text = "Name Height Weight Age
Alice 180 NA 35
Bob NA 80 27
Alice NA 70 NA
Charles 170 75 NA", header = TRUE)
答案 2 :(得分:2)
以下是data.table
library(data.table)
setDT(df)[, lapply(.SD, function(x) head(sort(x), 1)), Name]
# Name Height Weight Age
#1: Alice 180 70 35
#2: Bob NA 80 27
#3: Charles 170 75 NA
答案 3 :(得分:2)
只需在na.action=na.pass
电话中添加aggregate()
:
aggdf <- aggregate(.~Name, data=df, FUN=f, na.action=na.pass)
# Name Height Weight Age
# 1 Alice 180 70 35
# 2 Bob NA 80 27
# 3 Charles 170 75 NA
答案 4 :(得分:1)
如果您在函数中添加ifelse()
以确保函数返回值,如果所有值都为NA
:
f <- function(x) {
x <- x[!is.na(x)]
ifelse(length(x) == 0, NA, x)
}
您可以使用dplyr
汇总:
library(dplyr)
dt %>% group_by(Name) %>% summarise_all(funs(f))
返回:
# A tibble: 3 x 4
Name Height Weight Age
<fctr> <dbl> <dbl> <dbl>
1 Alice 180 70 35
2 Bob NA 80 27
3 Charles 170 75 NA