除了其他dplyr函数外,我喜欢在多个数据帧的for循环中使用dplyr mutate()函数。我有一个包含几个数据框的列表。目标是操作传递for循环的每个数据帧,以便在循环中可以使用新数据帧来获得目标分析。不幸的是,我不知道如何做到这一点。任何帮助都会非常感激!
下面我试图创建一个可重复的例子来说明我的目标是做什么。请注意,如果可以创建所需的数据文件,则会扩展for循环中的分析;但是,要回答这个问题,不需要进一步的分析。
因此,在本例中,我们将首先向传递循环的每个数据文件添加一个包含时间值的新变量。假设第一行是30秒,接下来的每一行应该是30秒后。
然后我们找到teststart(值5第一次出现在$ p中)和testend(值5第二次出现在$ p中)。基于teststart和testend,我们将datafile_wholemmeasurement缩减为datafile_testduration。 在datafile_testduration中,我们将创建一个新的变量testduration。Testduration应该可以计算为time_seconds_wholemmeasurement中的值减去teststart时time_seconds_wholemmeasurement的值。下面是它的工作原理:
d1 <- data.frame(P=c(1,5,2,3,4,7,5,6,7), E=c(4,5,6,4,5,6,4,5,6))
d2 <- data.frame(P=c(0,9,8,5,4,7,5), E=c(6,5,4,6,5,4,5))
d3 <- data.frame(P=c(6,5,4,6,5,4,6,5,4), E=c(3,2,1,5,5,5,5,5,5))
d4 <- data.frame(P=c(5,9,9,5,2,2,1,8,5,7,6,5),E=c(8,8,8,8,8,8,8,8,8,8,8,8))
file_contents <- list(d1, d2, d3, d4)
res <- data.frame(teststart = rep(NA,length(file_contents)), testend =rep(NA,length(file_contents)))
for(i in 1:length(file_contents))
{
datafile_wholemeasurement <- file_contents[[i]]
teststart <- which(file_contents[[i]]$P == 5)[1]
testend <- which(file_contents[[i]]$P == 5)[2]
datafile_testduration <- file_contents[[i]] %>%
filter(between(row_number(), teststart, testend-1))
res$teststart[[i]] <- teststart
res$testend[[i]] <- testend
}
这是我的尝试如何描述;它不工作:
for(i in 1:length(file_contents))
{
datafile_wholemeasurement <- file_contents[[i]] %>%
mutate(time_seconds_wholemeasurement = seq(from = 30, to = length(file_contents[[i]]$P)*30, by = 30))
teststart <- which(file_contents[[i]]$P == 5)[1]
testend <- which(file_contents[[i]]$P == 5)[2]
datafile_testduration <- file_contents[[i]] %>%
filter(between(row_number(), teststart, testend-1)) %>%
mutate(time_seconds_testduration = time_seconds_wholemeasurement - time_seconds_wholemeasurement[[1]])
res$teststart[[i]] <- teststart
res$testend[[i]] <- testend
}
再次感谢大家的支持。
"
我不知道我是否正确理解了你的问题。不过,他会尽力帮忙的。但让我们用r风格来做,没有不必要的for
循环,并保持主题尽可能简单。但是,由于这种方法对您来说可能有些晦涩,让我一步一步地指导您。
让我们从一个data frame
或tibble
(最好是data frame
)的数据准备开始
library(tidyverse)
df = tibble(
d = paste0("d", 1:4),
data = list(
tibble(P=c(1,5,2,3,4,7,5,6,7), E=c(4,5,6,4,5,6,4,5,6)),
tibble(P=c(0,9,8,5,4,7,5), E=c(6,5,4,6,5,4,5)),
tibble(P=c(6,5,4,6,5,4,6,5,4), E=c(3,2,1,5,5,5,5,5,5)),
tibble(P=c(5,9,9,5,2,2,1,8,5,7,6,5),E=c(8,8,8,8,8,8,8,8,8,8,8,8))
)
)
df
输出# A tibble: 4 x 2
d data
<chr> <list>
1 d1 <tibble [9 x 4]>
2 d2 <tibble [7 x 4]>
3 d3 <tibble [9 x 4]>
4 d4 <tibble [12 x 4]>
我知道这可能有点令人困惑。看看df$data[[1]]
data=df$data[[1]]
data
输出# A tibble: 9 x 2
P E
<dbl> <dbl>
1 1 4
2 5 5
3 2 6
4 3 4
5 4 5
6 7 6
7 5 4
8 6 5
9 7 6
你可以看到,这是data frame
中的data frame
。
现在让我们执行第一个函数,将您的测量时间添加到data frame
中的data frame
中。
add_ts = function(data) data %>% mutate(tswm = seq(1, length(data$P))*30)
看看这有多简单。我们来测试一下
add_ts(data)
# A tibble: 9 x 3
P E tswm
<dbl> <dbl> <dbl>
1 1 4 30
2 5 5 60
3 2 6 90
4 3 4 120
5 4 5 150
6 7 6 180
7 5 4 210
8 6 5 240
9 7 6 270
你料到了吗?我想是的。我们来做第二个增加测试时间的函数。这个比较难一点。
add_tsd = function(data){
tsdidx = (which(data$P==5)[1]):(which(data$P==5)[2]-1)
data = data %>% mutate(tstd = NA)
data$tstd[tsdidx]=seq(1,length(tsdidx))*30
data
}
让我们马上测试一下
add_tsd(data)
# A tibble: 9 x 3
P E tstd
<dbl> <dbl> <dbl>
1 1 4 NA
2 5 5 30
3 2 6 60
4 3 4 90
5 4 5 120
6 7 6 150
7 5 4 NA
8 6 5 NA
9 7 6 NA
将这两个功能合并为一个
add_ts_tsd = function(data) add_ts(data) %>% add_tsd()
add_ts_tsd(data)
# A tibble: 9 x 4
P E tswm tstd
<dbl> <dbl> <dbl> <dbl>
1 1 4 30 NA
2 5 5 60 30
3 2 6 90 60
4 3 4 120 90
5 4 5 150 120
6 7 6 180 150
7 5 4 210 NA
8 6 5 240 NA
9 7 6 270 NA
我们做得很好。好吧,我们现在就开始
df %>% mutate(data = map(data, add_ts_tsd))
# A tibble: 4 x 2
d data
<chr> <list>
1 d1 <tibble [9 x 4]>
2 d2 <tibble [7 x 4]>
3 d3 <tibble [9 x 4]>
4 d4 <tibble [12 x 4]>
嗯,你什么都看不到吗?好的,让我们得到这些内部的data frame
。
df %>% mutate(data = map(data, add_ts_tsd)) %>% unnest(data)
# A tibble: 37 x 5
d P E tswm tstd
<chr> <dbl> <dbl> <dbl> <dbl>
1 d1 1 4 30 NA
2 d1 5 5 60 30
3 d1 2 6 90 60
4 d1 3 4 120 90
5 d1 4 5 150 120
6 d1 7 6 180 150
7 d1 5 4 210 NA
8 d1 6 5 240 NA
9 d1 7 6 270 NA
10 d2 0 6 30 NA
宾果!任务完成。简单而优雅。首先,清晰。