将R中的大型数据帧与每列中的多个整数分开,然后求和整数

时间:2018-04-12 23:50:37

标签: r dataframe

我在R中有一个数据框,我从一个文本文件读入,其中有两列,每列有多个整数。我需要从另一列(End)中的相应整数中减去一列(Start)中的相应整数。我最终想要获得的最后一步是将所有距离相加以获得每个轨道的总距离。下面的数据框只是一个例子,但是有问题的数据框每列有大约20个整数,并且有几十个轨道(行)。

轨道A的

:( 15-6)+(20-5)+(7-1)

track     StartDist         EndDist
A         1, 5, 6           7, 20, 15
B         1, 7, 8, 11       6, 21, 22, 25

我会使用函数separate(),但每列的整数数量不相同。我还考虑重新构建数据帧,每行只包含一个整数,但最终会有成千上万行,然后必须再将它们组合起来计算每个轨道的总数。有什么建议?

3 个答案:

答案 0 :(得分:1)

这是一个dplyr解决方案,也使用stringr。我们使用rowwise()mutate将以下操作应用于每个行:str_split()将每个“Dist”列中的字符串分隔为字母数字字符串列表,然后不列出,强制转换为数字向量,并按您请求的顺序减去。然后对得到的数值向量的元素求和。

对于它的价值,我更喜欢基础R解决方案,所以我认为Maurits Evers的解决方案更优雅:

library(dplyr)
library(stringr)

track <- c("A", "B")
StartDist <- c("1, 5, 6", "1, 7, 8, 11")
EndDist <- c("7, 20, 15", "6, 21, 22, 25")

df <- data.frame(track,StartDist,EndDist)

df <- mutate(rowwise(df),
             sum = sum(as.numeric(unlist(str_split(EndDist, ","))) - as.numeric(unlist(str_split(StartDist, ",")))))

输出:

# A tibble: 2 x 4
  track StartDist   EndDist         sum
  <fct> <fct>       <fct>         <dbl>
1 A     1, 5, 6     7, 20, 15       30.
2 B     1, 7, 8, 11 6, 21, 22, 25   47.

答案 1 :(得分:1)

我真的建议将其存储为“长”字样。文件使任何后续分析更简单。如果你处于整齐的世界,我会做类似的事情:

library(tidyverse)

datlong <- dat %>%
  mutate_at(vars(StartDist, EndDist), str_split, ",\\s+") %>%
  unnest %>% 
  mutate_at(vars(StartDist, EndDist), as.numeric) 

datlong %>%
  group_by(track) %>%
  summarise(Len = sum(EndDist - StartDist))

# A tibble: 2 x 2
#  track   Len
#  <chr> <dbl>
#1     A    30
#2     B    47

dat的位置:

txt <- "track|StartDist|EndDist
A|1, 5, 6|7, 20, 15
B|1, 7, 8, 11|6, 21, 22, 25"

dat <- read.table(text=txt, sep="|", header=TRUE, stringsAsFactors=FALSE)

有趣和游戏的基础R翻译:

vars    <- c("StartDist", "EndDist")
othvars <- setdiff(names(dat), vars)
dat[vars] <- lapply(dat[vars], strsplit, ",\\s+")

datlong <- cbind(
  dat[othvars][rep(seq_len(nrow(dat)), lengths(dat[[vars[1]]])),, drop=FALSE],
  lapply(dat[vars], unlist),
  stringsAsFactors=FALSE
)
datlong[vars] <- lapply(datlong[vars], as.numeric)

aggregate(cbind(Len = EndDist - StartDist) ~ track, data=datlong, FUN=sum)

答案 2 :(得分:0)

这是基础R解决方案。我们使用splitsplt对条目进行分组,然后使用自定义函数StartDistEndDist", "列中的条目拆分为mapply;然后,我们使用sum.diff计算成对差异,并返回列splt <- function(x) as.numeric(unlist(strsplit(as.character(x), ", "))) df$sum.diff = sapply(split(df, df$track), function(x) { start <- splt(x$StartDist); end <- splt(x$EndDist); sum(mapply(function(a, b) b - a, start, end)) }); df; # track StartDist EndDist sum.diff #1 A 1, 5, 6 7, 20, 15 30 #2 B 1, 7, 8, 11 6, 21, 22, 25 47 中所有成对距离的总和。

df <- read.table(text =
    "track     StartDist         EndDist
A         '1, 5, 6'           '7, 20, 15'
B         '1, 7, 8, 11'       '6, 21, 22, 25'", header = T)

样本数据

net rpc service list
net rpc service start
net rpc service stop