我在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()
,但每列的整数数量不相同。我还考虑重新构建数据帧,每行只包含一个整数,但最终会有成千上万行,然后必须再将它们组合起来计算每个轨道的总数。有什么建议?
答案 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解决方案。我们使用split
按splt
对条目进行分组,然后使用自定义函数StartDist
将EndDist
和", "
列中的条目拆分为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