R对data.frame的行进行求和,仅包含某列中的数字

时间:2017-03-28 14:44:41

标签: r dataframe numbers subset

如何仅对b列中包含数字的行求和。

a <- c(1,5,3,1,-8,6,-1)
b <- c(4,-2,1,0,"c",2,"DX")

df <- data.frame(a,b)
df

#    a  b
# 1  1  4
# 2  5 -2
# 3  3  1
# 4  1  0
# 5 -8  c
# 6  6  2
# 7 -1  DX

我似乎无法总结只有columb b的数字行。

实际上我有多个数据来自我读取的多个csv文件,并使用以下代码以数据帧的形式存储在r中:

path <- "C:/Users/Visitor/Desktop/Unesco/"
files <- list.files(path=path, pattern="*.csv")
for(file in files)
{
perpos <- which(strsplit(file, "")[[1]]==".")
assign(
gsub(" ","",substr(file, 1, perpos-1)), 
read.csv(paste(path,file,sep="")))
}

我可以通过输入他们的名字(csv文件)来阅读它们

问题是有些列包含数字和字符,所以我不能对它们做一个简单的求和。

2 个答案:

答案 0 :(得分:2)

我建议您在创建stringsAsFactors = FALSE时使用data.frame或在现有data.frame中将因素转换为字符。然后,您可以将数值提取到新列中,您可以使用常规的tidyverse工具进行求和。


library(tidyverse)

a <- c(1,5,3,1,-8,6,-1)
b <- c(4,-2,1,0,"c",2,"DX")

df <- data.frame(a, b, stringsAsFactors = F)

df %>% 
  mutate(b_numbers = parse_double(b)) %>% 
  summarise(sum = sum(b_numbers, na.rm = T))
#> Warning: 2 parsing failures.
#> row col expected actual
#>   5  -- a double     c 
#>   7  -- a double     DX
#>   sum
#> 1   5

这种方法很好地适用于处理多个列:

df %>% 
  mutate_all(funs(parse_double)) %>% 
  summarise_all(funs(sum(., na.rm = T)))
#> Warning: 2 parsing failures.
#> row col expected actual
#>   5  -- a double     c 
#>   7  -- a double     DX
#>   a b
#> 1 7 5

如果你有很多这样的data.frame,你可以把它变成一个函数并将它映射到你的列表:

my_fun <- function(x) {
  x %>% 
    mutate_all(funs(suppressWarnings(parse_double(.)))) %>% 
    summarise_all(funs(sum(., na.rm = T)))
}

# create list with multiple data.frames
my_list <- list(a = df, b = df)

my_list %>% 
  map(my_fun)
#> $a
#>   a b
#> 1 7 5
#> 
#> $b
#>   a b
#> 1 7 5

d.b指出的一样,您可以使用suppressWarnings()来消除parse_double的警告。在此示例中,我希望parse_double超过as.numeric,因为它可以提供有关正在发生的事情的信息。

修改: 由于您在对原始问题的评论中说明了data.frame的列始终具有相同的名称,因此您可以使用mutate_atsummarise_at

my_fun <- function(x) {
  x %>% 
    mutate_at("b", funs(suppressWarnings(parse_double(.)))) %>% 
    summarise_at("b", funs(sum(., na.rm = T)))
}

或多列:

my_fun <- function(x) {
  x %>% 
    mutate_at(c("a", "b"), funs(suppressWarnings(parse_double(.)))) %>% 
    summarise_at(c("a", "b"), funs(sum(., na.rm = T)))
}

答案 1 :(得分:0)

如果您想逐行求和:

a <- c(1,5,3,1,-8,6,-1)
b <- c(4,-2,1,0,"c",2,"DX")

df <- data.frame(a,b = as.numeric(b))
rowSums(df)

仅适用于非na的:

rowSums(df[!is.na(df$b),])

如果你想按列:

colSums(df[!is.na(df$b),])

或取决于你想在列中总结的内容:

colSums(df, na.rm = TRUE)