R 当第2列中的值第一次超过2时,返回第1列中的值
我有一个名为“new_dat”的数据框,其中t列包含时间(天),a-C列包含温度数据(有时是NA)(请参见下面代码中的示例): 以下是数据帧的dput():R 当第2列中的值第一次超过2时,返回第1列中的值,r,loops,R,Loops,我有一个名为“new_dat”的数据框,其中t列包含时间(天),a-C列包含温度数据(有时是NA)(请参见下面代码中的示例): 以下是数据帧的dput(): structure(list(t = c(0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.11), A = c(0.82, 0.870000000000001, NA, 0.949999999999999, 0.979999999999997, 1.01,
structure(list(t = c(0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07,
0.08, 0.09, 0.1, 0.11), A = c(0.82, 0.870000000000001, NA,
0.949999999999999,
0.979999999999997, 1.01, 2, 1.06, 1.07, 1.09, 1.1, 2), B =
c(0.879999999999999,
0.940000000000001, NA, 1.03, 1.06, 1.09, 1.13, 1.16, 1.18, 1.2,
1.21, 1.22), C = c(0.460000000000001, 0.520000000000003, NA,
0.619999999999997, 0.669999999999998, 0.709999999999997, 2,
0.780000000000001,
0.809999999999999, 0.84, 0.859999999999999, 0.87)), .Names = c("t",
"A", "B", "C"), row.names = c(NA, 12L), class = "data.frame")
作为输出,我需要一个列t值的向量(列表?),其中a-C列的温度读数第一次(并且仅第一次)大于等于2,或者-如果温度从未大于等于2-返回t列的最后一次读数(在我的示例中为0.11)。因此,“A”将返回值0.06(而不是0.11),“B”将返回值0.11和“C”0.06。我打算使用生成的向量创建一个新的数据帧,如下所示:
A B C
0.06 0.11 0.06
我对R(以及一般的代码)缺乏经验,因此,尽管读到循环可能是无效的(但并不真正理解如何在没有它的情况下实现我想要的),我还是尝试通过先按列循环,然后按行循环来解决这个问题,如下所示:
#create blank vector to add my results to
aer <- c()
#loop by column, then by row, adding values according to the if statement
for (c in 2:ncol(new_dat)){
c <- c
for (r in 1:nrow(new_dat)){
r <- r
if ((!is.na(new_dat[r,c] )) & (new_dat[r,c] >= 2)){
aer <- c(aer, new_dat$t[r])
}
}
}
因此,它将返回两个实例,其中“A”是2,而“C”列中的一个实例
我不知道如何指示循环停止并在找到我的'if'语句为真的一个实例后移动到下一列。我还尝试添加一个“else”来涵盖温度不超过2的情况:
else {
aer <- c(aer, new_dat$t[nrow(new_dat)])
else{
aer这是一个两步解决方案。
首先获取所需值的索引向量,然后使用该索引向量对数据帧进行子集
inx <- sapply(new_dat[-1], function(x) {
w <- which(x >= 2)
if(length(w)) min(w) else NROW(x)
})
new_dat[inx, 1]
#[1] 0.06 0.11 0.06
inx这里有一个两步解决方案。
首先获取所需值的索引向量,然后使用该索引向量对数据帧进行子集
inx <- sapply(new_dat[-1], function(x) {
w <- which(x >= 2)
if(length(w)) min(w) else NROW(x)
})
new_dat[inx, 1]
#[1] 0.06 0.11 0.06
inxlibrary(tidyverse)
新数据%>%
聚集(列,温度,-t)%>%#重塑数据
na.omit()%>%#删除带有NAs的行
按(列)%>%对每列值进行分组
总结(v=ifelse(is.na(first(t[temp>=2])、last(t)、first(t[temp>=2]))%%>%#如果没有temp>=2,则返回最后的t值,否则返回temp>=2的第一个t
展开(col,v)#再次重塑
##A tible:1 x 3
#A、B、C
#
# 1 0.06 0.11 0.06
此解决方案将自动为您创建数据帧,而不是返回一个向量供您自己创建数据帧。库(tidyverse)
新数据%>%
聚集(列,温度,-t)%>%#重塑数据
na.omit()%>%#删除带有NAs的行
按(列)%>%对每列值进行分组
总结(v=ifelse(is.na(first(t[temp>=2])、last(t)、first(t[temp>=2]))%%>%#如果没有temp>=2,则返回最后的t值,否则返回temp>=2的第一个t
展开(col,v)#再次重塑
##A tible:1 x 3
#A、B、C
#
# 1 0.06 0.11 0.06
此解决方案将自动为您创建数据框,而不是返回一个向量供您自己创建数据框。检查您的要求,您的任何列的差异都不会超过2(请参阅您对a-C>=2的描述),并且据我所知,对于所有行B>a>C(a==2.0除外)。请检查您的要求,实际上,您的所有列的差异都不超过2(请参阅您对A-C>=2的描述),并且,据我所知,对于所有行B>A>C(A==2.0除外)。感谢您的解决方案。我在安装tidyverse库时遇到问题,但是安装了一些软件包。您能告诉我使用您的解决方案需要哪些软件包吗?我猜了一下dplyr和tidyr,但我得到了“总结中出错(.data,dots):不支持的向量类型语言”是的,这确实是两个软件包。也许你有这些软件包的旧版本?我正在使用dplyr 0.7.6
和tidyr 0.8.1
谢谢-你说得对,我正在运行这两个软件包的旧版本。当我尝试安装时仍然会出错-我将进一步研究。再次感谢你的帮助,非常感谢!我已将此标记为解决方案创建了我想要的数据帧。我唯一不太理解的部分是“摘要”部分。检查如下:iffirst(t[temp>=2])
返回NA,返回t
的最后一个值;否则返回t
的第一次值是=2
?感谢您的解决方案。我在安装tidyverse库时遇到了问题,但是已经安装了一些软件包。您能告诉我使用您的解决方案需要哪些软件包吗?我猜测了dplyr和tidyr,但我得到了“总结中的错误(.data,dots):不支持的向量类型语言”是的,这确实是两个软件包。也许你有这些软件包的旧版本?我正在使用dplyr 0.7.6
和tidyr 0.8.1
谢谢-你说得对,我正在运行这两个软件包的旧版本。当我尝试安装时仍然会出错-我将进一步研究。再次感谢你的帮助,非常感谢!我已将此标记为这个解决方案创建了我想要的数据帧。我唯一不太理解的部分是“摘要”部分。这个检查如下:如果first(t[temp>=2])
返回NA,则返回t
的最后一个值;否则返回第一次t
是=2
?
inx <- sapply(new_dat[-1], function(x) {
w <- which(x >= 2)
if(length(w)) min(w) else NROW(x)
})
new_dat[inx, 1]
#[1] 0.06 0.11 0.06
library(tidyverse)
new_dat %>%
gather(col, temp, -t) %>% # reshape data
na.omit() %>% # remove rows with NAs
group_by(col) %>% # for each column value
summarise(v = ifelse(is.na(first(t[temp >= 2])), last(t), first(t[temp >= 2]))) %>% # return the last t value if there are no temp >=2 otherwise return the first t with temp >= 2
spread(col, v) # reshape again
# # A tibble: 1 x 3
# A B C
# <dbl> <dbl> <dbl>
# 1 0.06 0.11 0.06