R - Return 找到第一个给定值的行的列名
R - Return column name for row where first given value is found
我试图在数据帧中为每一行 值找到第一次出现 FALSE。我的行是特定事件,列是日期。我希望能够找到第一个 FALSE 的日期,以便我可以使用该值找到 return 日期。
我的数据框的示例结构:
df <- data.frame(ID = c(1,2,3), '2001' = c(TRUE, TRUE, TRUE),
'2002' = c(FALSE, TRUE, FALSE), '2003' = c(TRUE, FALSE, TRUE))
我想以第二个数据框或列表结束,其中包含标识第一个 FALSE 实例的 ID 和列名。
例如:
ID | Date
1 | 2002
2 | 2003
3 | 2002
我不知道找到这样结果的机制。
实际的数据框包含几千行,所以很遗憾我无法手动完成。
我是 R 的新用户,所以请不要提出一些您可能认为更有经验的 R 用户已经考虑过的事情。
提前致谢
使用 tidyverse
函数试试这个。您可以将数据整形为长数据,然后过滤 F
值。如果有一些重复的行,第二个过滤器可以避免它们。这里的代码:
library(dplyr)
library(tidyr)
#Code
newdf <- df %>% pivot_longer(-ID) %>%
group_by(ID) %>%
filter(value==F) %>%
filter(!duplicated(value)) %>% select(-value) %>%
rename(Myname=name)
输出:
# A tibble: 3 x 2
# Groups: ID [3]
ID Myname
<dbl> <chr>
1 1 2002
2 2 2003
3 3 2002
另一个没有重复值的选项可以使用 row_number()
提取第一个值 (row_number()==1
):
library(dplyr)
library(tidyr)
#Code 2
newdf <- df %>% pivot_longer(-ID) %>%
group_by(ID) %>%
filter(value==F) %>%
mutate(V=ifelse(row_number()==1,1,0)) %>%
filter(V==1) %>%
select(-c(value,V)) %>% rename(Myname=name)
输出:
# A tibble: 3 x 2
# Groups: ID [3]
ID Myname
<dbl> <chr>
1 1 2002
2 2 2003
3 3 2002
或将 base R
与 apply()
和通用函数一起使用:
#Code 3
out <- data.frame(df[,1,drop=F],Res=apply(df[,-1],1,function(x) names(x)[min(which(x==F))]))
输出:
ID Res
1 1 2002
2 2 2003
3 3 2002
我们可以在反转逻辑值后使用 max.col
和 ties.method = 'first'
。
cbind(df[1], Date = names(df[-1])[max.col(!df[-1], ties.method = 'first')])
# ID Date
#1 1 2002
#2 2 2003
#3 3 2002
我试图在数据帧中为每一行 值找到第一次出现 FALSE。我的行是特定事件,列是日期。我希望能够找到第一个 FALSE 的日期,以便我可以使用该值找到 return 日期。
我的数据框的示例结构:
df <- data.frame(ID = c(1,2,3), '2001' = c(TRUE, TRUE, TRUE),
'2002' = c(FALSE, TRUE, FALSE), '2003' = c(TRUE, FALSE, TRUE))
我想以第二个数据框或列表结束,其中包含标识第一个 FALSE 实例的 ID 和列名。
例如:
ID | Date
1 | 2002
2 | 2003
3 | 2002
我不知道找到这样结果的机制。
实际的数据框包含几千行,所以很遗憾我无法手动完成。
我是 R 的新用户,所以请不要提出一些您可能认为更有经验的 R 用户已经考虑过的事情。
提前致谢
使用 tidyverse
函数试试这个。您可以将数据整形为长数据,然后过滤 F
值。如果有一些重复的行,第二个过滤器可以避免它们。这里的代码:
library(dplyr)
library(tidyr)
#Code
newdf <- df %>% pivot_longer(-ID) %>%
group_by(ID) %>%
filter(value==F) %>%
filter(!duplicated(value)) %>% select(-value) %>%
rename(Myname=name)
输出:
# A tibble: 3 x 2
# Groups: ID [3]
ID Myname
<dbl> <chr>
1 1 2002
2 2 2003
3 3 2002
另一个没有重复值的选项可以使用 row_number()
提取第一个值 (row_number()==1
):
library(dplyr)
library(tidyr)
#Code 2
newdf <- df %>% pivot_longer(-ID) %>%
group_by(ID) %>%
filter(value==F) %>%
mutate(V=ifelse(row_number()==1,1,0)) %>%
filter(V==1) %>%
select(-c(value,V)) %>% rename(Myname=name)
输出:
# A tibble: 3 x 2
# Groups: ID [3]
ID Myname
<dbl> <chr>
1 1 2002
2 2 2003
3 3 2002
或将 base R
与 apply()
和通用函数一起使用:
#Code 3
out <- data.frame(df[,1,drop=F],Res=apply(df[,-1],1,function(x) names(x)[min(which(x==F))]))
输出:
ID Res
1 1 2002
2 2 2003
3 3 2002
我们可以在反转逻辑值后使用 max.col
和 ties.method = 'first'
。
cbind(df[1], Date = names(df[-1])[max.col(!df[-1], ties.method = 'first')])
# ID Date
#1 1 2002
#2 2 2003
#3 3 2002