为列表中的每个数据框创建一个包含列总和的新行

May*_*yla 2 r sum coercion lapply

我有一个多个数据框的列表.示例数据:

df1 <- data.frame(Name=c("A", "B", "C"), E1=c(0, NA, 1), E2=c(1, 0, 1))
df2 <- data.frame(Name=c("A", "C", "F"), E1=c(1, 0, 1), E2=c(0, 0, 0))
ls <- list(df1, df2)
Run Code Online (Sandbox Code Playgroud)

对于每个数据框,我想在底部创建一个包含每列总和的新行.所以对于df1来说会是这样的:

Name E1 E2
"A"  0  1
"B"  NA 0
"C"  1  1
Sum  1  2
Run Code Online (Sandbox Code Playgroud)

这是我试过的:

ls <- lapply(ls, function(x) {
  x[nrow(x)+1, -1] <- colSums(x[,-1], na.rm=TRUE)
})
Run Code Online (Sandbox Code Playgroud)

我收到以下错误消息:

Error in colSums(x[,-1], na.rm = TRUE) : 'x' must be numeric
Run Code Online (Sandbox Code Playgroud)

除"名称"之外的所有列都只包含1,0和NA,因此我认为可能它们被读作因子而不是数字.我第一次尝试强制数字(看起来像下面的函数,但没有"unlist")导致错误(对象类型列表不能被强制键入'double')所以我根据其他帖子中的答案尝试了以下内容:

ls <- lapply(ls, function(x) {
  x[,-1] <- as.numeric(unlist(x[,-1]))
})
Run Code Online (Sandbox Code Playgroud)

但这只是给我一个数字字符串列表,而不是我想要的数据帧列表.任何关于修复我的原始colSums功能或成功将我的数据转换为数字的建议都将非常感谢!

Cal*_*You 5

你很亲密!您当前的函数仅返回最后一行,因为默认情况下函数会返回最后一行中的任何对象.所以你需要类似下面这样的东西.as.character是因为字符串是作为因子输入的,这不会让你"Sum"以正确的方式进入框架.

一般情况下,除非这是某种输出存储汇总统计信息作为表中的一行不是一个非常整洁的做法,因为它可能会让一些行包含数据而其他行包含数据而变得混乱.

df1 <- data.frame(Name=c("A", "B", "C"), E1=c(0, NA, 1), E2=c(1, 0, 1))
df2 <- data.frame(Name=c("A", "C", "F"), E1=c(1, 0, 1), E2=c(0, 0, 0))
ls <- list(df1, df2)

lapply(ls, function(x) {
  x[nrow(x)+1, -1] <- colSums(x[,-1], na.rm=TRUE)
  x[, 1] <- as.character(x[, 1])
  x[nrow(x), 1] <- "Sum"
  return(x)
})
#> [[1]]
#>   Name E1 E2
#> 1    A  0  1
#> 2    B NA  0
#> 3    C  1  1
#> 4  Sum  1  2
#> 
#> [[2]]
#>   Name E1 E2
#> 1    A  1  0
#> 2    C  0  0
#> 3    F  1  0
#> 4  Sum  2  0
Run Code Online (Sandbox Code Playgroud)

由reprex包(v0.2.0)于2018-03-16创建.