在数据框中搜索多个字符串,如果有条件则自下而上?
Searching for multiple strings in dataframe, bottom up in if conditional?
我有一个包含多列的数据框,我们称之为 dat1,我需要根据很多条件提取某些列中的字符串。
每个主题有 350 行,我需要在每个主题的特定列中找到特定字符串的最后一个,包含特定名称,例如"green",并从同一行的另一个字符串中取值。
subject type value
111 yellow 354
111 green 584
111 yellow 584
111 blue 492
111 green 493
222 blue 459
222 green 583
222 yellow 539
222 blue 392
222 yellow 394
假设我需要每个主题的最后一个值 "green",我该怎么做?
这样做之后,我还需要获取高于最后一个 "green" 的值,最好将它们保存在两个单独的向量中。
last_green before_last_green
493 492
583 459
我曾尝试制作多个 if 语句,同时还按主题分组,但几乎没有成功。我之前也找不到任何这方面的例子。
是否可以从每个主题的底部搜索第一个"green"?或者如何执行此操作?
代码
tidyverse
是你的朋友:
library(tidyverse)
d <- structure(list(subject = c(111L, 111L, 111L, 111L, 111L,
222L, 222L, 222L, 222L, 222L),
type = c("yellow", "green", "yellow", "blue", "green",
"blue", "green", "yellow", "blue", "yellow"),
value = c(354L, 584L, 584L, 492L, 493L,
459L, 583L, 539L, 392L, 394L)),
row.names = c(NA, -10L),
class = c("tbl_df", "tbl", "data.frame"))
d %>%
group_by(subject) %>%
filter(type == "green") %>%
summarise_all(last)
# A tibble: 2 x 3
# subject type value
# <int> <chr> <int>
# 1 111 green 493
# 2 222 green 583
说明
- 对于
group_by
,您将根据 subject
的唯一值执行以下操作
- 与
filter
你只查找 type
等于 green
的行
- 和
summarise
你终于select只剩下最后一个条目
回答两个问题:
df=data.frame("subject"=c(rep(111,5),rep(222,5)),
"type"=c("yellow","green","yellow","blue","green",
"blue","green","yellow","blue","yellow"),
value=c(354,584,584,492,493,459,583,539,392,394),
stringsAsFactors = FALSE)
subject type value
1 111 yellow 354
2 111 green 584
3 111 yellow 584
4 111 blue 492
5 111 green 493
6 222 blue 459
7 222 green 583
8 222 yellow 539
9 222 blue 392
10 222 yellow 394
创建过滤器 df:
filter_=df%>%rownames_to_column()%>%group_by(subject)%>%
filter(type=="green")%>%slice(n())
last_green=filter_$value
before_last_green=df$value[as.numeric(filter_$rowname)-1]
结果:
> last_green
[1] 493 583
> before_last_green
[1] 492 459
解释:
我们首先创建行名来跟踪每个 subject
最后 green
出现的位置。然后,我们按 subject
分组并按 type
过滤我们用 slice()
取每组的最后一个元素。然后我们 return last_green
中的 value
和具有这些先前样本位置的行的 value
- 1(前一个)。
你可以这样做:
library(tidyverse)
dat %>%
rownames_to_column() %>%
group_by(subject) %>%
filter(type == 'green') %>%
summarise(
last_green = last(value),
before_last_green = dat$value[as.numeric(last(rowname)) - 1]
)
这里发生了什么:
- 您将
data.frame
的行名移动到变量 rowname
中(请参阅后面的原因);
- 您按
subject
对数据进行分组,以对与特定 subject
; 相关的数据子集应用以下操作
- 你
filter
你的数据,只剩下greens
;
- 最后:
- 你
summarize
你的数据,为每个先前 过滤的 子集获取最后 value
,并将其分配给 value_green
;
- 您从环境中借用了整个未转换的
dat
,通过对应于 .
的 last(ronwame) - 1
的行从 dat
中子集 value
数据,即通过管道进入 summarize
的数据。
计算结果为:
# A tibble: 2 x 3
subject last_green before_last_green
<int> <int> <int>
1 111 493 492
2 222 583 459
您的数据:
dat <- read.table(
text = "subject type value
111 yellow 354
111 green 584
111 yellow 584
111 blue 492
111 green 493
222 blue 459
222 green 583
222 yellow 539
222 blue 392
222 yellow 394",
header = T, stringsAsFactors = F
)
我有一个包含多列的数据框,我们称之为 dat1,我需要根据很多条件提取某些列中的字符串。 每个主题有 350 行,我需要在每个主题的特定列中找到特定字符串的最后一个,包含特定名称,例如"green",并从同一行的另一个字符串中取值。
subject type value
111 yellow 354
111 green 584
111 yellow 584
111 blue 492
111 green 493
222 blue 459
222 green 583
222 yellow 539
222 blue 392
222 yellow 394
假设我需要每个主题的最后一个值 "green",我该怎么做?
这样做之后,我还需要获取高于最后一个 "green" 的值,最好将它们保存在两个单独的向量中。
last_green before_last_green
493 492
583 459
我曾尝试制作多个 if 语句,同时还按主题分组,但几乎没有成功。我之前也找不到任何这方面的例子。
是否可以从每个主题的底部搜索第一个"green"?或者如何执行此操作?
代码
tidyverse
是你的朋友:
library(tidyverse)
d <- structure(list(subject = c(111L, 111L, 111L, 111L, 111L,
222L, 222L, 222L, 222L, 222L),
type = c("yellow", "green", "yellow", "blue", "green",
"blue", "green", "yellow", "blue", "yellow"),
value = c(354L, 584L, 584L, 492L, 493L,
459L, 583L, 539L, 392L, 394L)),
row.names = c(NA, -10L),
class = c("tbl_df", "tbl", "data.frame"))
d %>%
group_by(subject) %>%
filter(type == "green") %>%
summarise_all(last)
# A tibble: 2 x 3
# subject type value
# <int> <chr> <int>
# 1 111 green 493
# 2 222 green 583
说明
- 对于
group_by
,您将根据subject
的唯一值执行以下操作
- 与
filter
你只查找type
等于green
的行
- 和
summarise
你终于select只剩下最后一个条目
回答两个问题:
df=data.frame("subject"=c(rep(111,5),rep(222,5)),
"type"=c("yellow","green","yellow","blue","green",
"blue","green","yellow","blue","yellow"),
value=c(354,584,584,492,493,459,583,539,392,394),
stringsAsFactors = FALSE)
subject type value
1 111 yellow 354
2 111 green 584
3 111 yellow 584
4 111 blue 492
5 111 green 493
6 222 blue 459
7 222 green 583
8 222 yellow 539
9 222 blue 392
10 222 yellow 394
创建过滤器 df:
filter_=df%>%rownames_to_column()%>%group_by(subject)%>%
filter(type=="green")%>%slice(n())
last_green=filter_$value
before_last_green=df$value[as.numeric(filter_$rowname)-1]
结果:
> last_green
[1] 493 583
> before_last_green
[1] 492 459
解释:
我们首先创建行名来跟踪每个 subject
最后 green
出现的位置。然后,我们按 subject
分组并按 type
过滤我们用 slice()
取每组的最后一个元素。然后我们 return last_green
中的 value
和具有这些先前样本位置的行的 value
- 1(前一个)。
你可以这样做:
library(tidyverse)
dat %>%
rownames_to_column() %>%
group_by(subject) %>%
filter(type == 'green') %>%
summarise(
last_green = last(value),
before_last_green = dat$value[as.numeric(last(rowname)) - 1]
)
这里发生了什么:
- 您将
data.frame
的行名移动到变量rowname
中(请参阅后面的原因); - 您按
subject
对数据进行分组,以对与特定subject
; 相关的数据子集应用以下操作
- 你
filter
你的数据,只剩下greens
; - 最后:
- 你
summarize
你的数据,为每个先前 过滤的 子集获取最后value
,并将其分配给value_green
; - 您从环境中借用了整个未转换的
dat
,通过对应于.
的last(ronwame) - 1
的行从dat
中子集value
数据,即通过管道进入summarize
的数据。
- 你
计算结果为:
# A tibble: 2 x 3
subject last_green before_last_green
<int> <int> <int>
1 111 493 492
2 222 583 459
您的数据:
dat <- read.table(
text = "subject type value
111 yellow 354
111 green 584
111 yellow 584
111 blue 492
111 green 493
222 blue 459
222 green 583
222 yellow 539
222 blue 392
222 yellow 394",
header = T, stringsAsFactors = F
)