Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用R中的自定义函数聚合data.frame中的多个列?_R_Dataframe_Aggregate - Fatal编程技术网

如何使用R中的自定义函数聚合data.frame中的多个列?

如何使用R中的自定义函数聚合data.frame中的多个列?,r,dataframe,aggregate,R,Dataframe,Aggregate,我有一个data.framedt,有一些重复的键和丢失的数据,即 Name Height Weight Age Alice 180 NA 35 Bob NA 80 27 Alice NA 70 NA Charles 170 75 NA 在本例中,键是名称,我想对每个列应用一个函数,如 f <- function(x){ x <-

我有一个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)
  }
我试过了

dt_agg <- aggregate(. ~ Name,
                    data = dt,
                    FUN = f)

dt_agg您可以使用
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)

您非常熟悉
aggregate
函数,需要调整aggregate处理
NA
的方式(从
NA.ommit
NA.pass
)。我的猜测是,aggregate首先删除带有NA的所有行,然后进行聚合,而不是在aggregate迭代要聚合的列时删除NAs。由于您的示例数据帧中的每一行都有一个
NA
,最终得到的是一个0行数据帧(这是我在运行代码时遇到的错误)。我通过删除除一个NA之外的所有NA来测试这一点,并且您的代码按原样工作。所以我们设置
na.action=na.pass
来传递na

dt_agg <- aggregate(. ~ Name,
                    data = dt,
                    FUN = f, na.action = "na.pass")
dt_agg如果在函数中添加一个
ifelse()
,以确保函数在所有值均为
NA
时返回一个值:

f <- function(x) {
  x <- x[!is.na(x)]
  ifelse(length(x) == 0, NA, x)
}
这将返回:

# 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
#一个tible:3 x 4
姓名身高体重年龄
1爱丽丝180 70 35
2 Bob NA 80 27
3查尔斯170 75纳

这里有一个带有
数据的选项。表

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

只需在
aggregate()中添加
na.action=na.pass
call:

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
aggdf
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
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
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