一次索引并分配多组行
Index and assign multiple sets of rows at once
我有一个导入的数据框 Measurements
,其中包含许多来自实验的观察结果。
Measurements <- data.frame(X = 1:4,
Data = c(90, 85, 100, 105))
X Data
1 90
2 85
3 100
4 105
我想添加 另一列 Condition
指定每个数据点 的治疗组 。我知道哪个观察范围来自哪个条件(例如,观察 1:2
来自对照组,观察 3:4
来自实验组)。
我已经设计了两个解决方案,可以提供所需的输出,但两个都不理想。第一:
Measurements["Condition"] <- c(rep("Cont", 2), rep("Exp", 2))
X Data Condition
1 90 Cont
2 85 Cont
3 100 Exp
4 105 Exp
这样做的好处是它是code/one命令的一行。但这并不理想,因为我需要在外部单独进行数学运算(例如 3:4 = 2 obs 等),这可以是 tricky/unclear/indirect,具有更大的数据集和更多条件(例如 47:83 = ? obs 等)并且可能会 永久性错误 因为早期分配的长度上的小错误也会改变后来组的分配(例如如果 Cont 的 rep 错误地为 1,则 Exp 也被错误地分配给 2:3)。
我也想过这样赋值,它也给出了想要的输出:
Measurements[1:2, "Condition"] <- "Cont"
Measurements[3:4, "Condition"] <- "Exp"
X Data Condition
1 90 Cont
2 85 Cont
3 100 Exp
4 105 Exp
这使得clear/simple/direct 哪些行将接受哪些分配,但这需要单独的分配和重复。我觉得应该有一种方法可以 “矢量化” 这个作业,这就是我正在寻找的 解决方案 。
我无法从网上找到复杂的索引规则。这是我对如何实现这一点的第一个直观 猜测:
Measurements[c(1:2, 3:4), "Condition"] <- list("Cont", "Exp")
X Data Condition
1 90 Cont
2 85 Cont
3 100 Cont
4 105 Cont
但这不起作用。它似乎将 1:2 和 3:4 组合成一个等效范围 (1:4) 并仅将第一个条件分配给该范围,这表明我还需要再次指定该列。当我再次尝试指定列时:
Measurements[c(1:2, 3:4), c("Condition", "Condition")] <- list("Cont", "Exp")
X Data Condition Condition.1
1 90 Cont Exp
2 85 Cont Exp
3 100 Cont Exp
4 105 Cont Exp
出于某种原因,这创建了第二个新列 (??),而且它似乎再次将 1:2 和 3:4 合并为 1:4。所以我想我需要索引 two row ranges 以保持它们 separate 并且只指定一次列,但我被卡住了关于如何做到这一点。我认为解决方案很简单,但我似乎找不到我正在尝试做的事情的例子。也许为了让它们分开,我必须单独分配它们,但我希望有办法。
有人可以帮忙吗?非常感谢 R 新手!
如果您已经有了属于每个条件的观察列表,您可以使用 dplyr::case_when
进行条件变异。根据您存储此信息的方式,您可以使用如下内容:
library(dplyr)
Measurements <- data.frame(X = 1:4,
Data = c(90, 85, 100, 105))
# set which observations belong to each condition
Cont <- 1:2
Exp <- 3:4
Measurements %>%
mutate(Condition = case_when(
X %in% Cont ~ "Cont",
X %in% Exp ~ "Exp"
))
# X Data Condition
# 1 90 Cont
# 2 85 Cont
# 3 100 Exp
# 4 105 Exp
请注意,这不要求观察结果在连续的行中。
了解数据模式和数据 ID 对较大的数据集很有效。
Measurements <- data.frame(X = 1:4, Data = c(90, 85, 100, 105))
dat <- c("Cont","Exp")
pattern <- c(1,1,2,2)
或者从数据中绘制图案,例如条件来自 Measurements$Data
pattern <- sapply( Measurements$Data >=100, function(x){ if(x){2}else{1} } )
# [1] 1 1 2 2
然后你可以简单地添加数据:
Measurements$Condition <- dat[pattern]
# X Data Condition
#1 1 90 Cont
#2 2 85 Cont
#3 3 100 Exp
#4 4 105 Exp
我通常看到这是通过合并操作完成的。诀窍是让您的条件数据变得漂亮。
composeConditions <- function(...) {
conditions <- list(...)
data.frame(
X = unname(unlist(conditions)),
condition = unlist(unname(lapply(
names(conditions),
function(x) rep(x, times = length(conditions[x][[1]]))
)))
)
}
conditions <- composeConditions(Cont = 1:2, Exp = 3:4)
> conditions
X condition
1 1 Cont
2 2 Cont
3 3 Exp
4 4 Exp
merge(Measurements, conditions, by = "X")
X Data condition
1 1 90 Cont
2 2 85 Cont
3 3 100 Exp
4 4 105 Exp
我有一个导入的数据框 Measurements
,其中包含许多来自实验的观察结果。
Measurements <- data.frame(X = 1:4,
Data = c(90, 85, 100, 105))
X Data
1 90
2 85
3 100
4 105
我想添加 另一列 Condition
指定每个数据点 的治疗组 。我知道哪个观察范围来自哪个条件(例如,观察 1:2
来自对照组,观察 3:4
来自实验组)。
我已经设计了两个解决方案,可以提供所需的输出,但两个都不理想。第一:
Measurements["Condition"] <- c(rep("Cont", 2), rep("Exp", 2))
X Data Condition
1 90 Cont
2 85 Cont
3 100 Exp
4 105 Exp
这样做的好处是它是code/one命令的一行。但这并不理想,因为我需要在外部单独进行数学运算(例如 3:4 = 2 obs 等),这可以是 tricky/unclear/indirect,具有更大的数据集和更多条件(例如 47:83 = ? obs 等)并且可能会 永久性错误 因为早期分配的长度上的小错误也会改变后来组的分配(例如如果 Cont 的 rep 错误地为 1,则 Exp 也被错误地分配给 2:3)。
我也想过这样赋值,它也给出了想要的输出:
Measurements[1:2, "Condition"] <- "Cont"
Measurements[3:4, "Condition"] <- "Exp"
X Data Condition
1 90 Cont
2 85 Cont
3 100 Exp
4 105 Exp
这使得clear/simple/direct 哪些行将接受哪些分配,但这需要单独的分配和重复。我觉得应该有一种方法可以 “矢量化” 这个作业,这就是我正在寻找的 解决方案 。
我无法从网上找到复杂的索引规则。这是我对如何实现这一点的第一个直观 猜测:
Measurements[c(1:2, 3:4), "Condition"] <- list("Cont", "Exp")
X Data Condition
1 90 Cont
2 85 Cont
3 100 Cont
4 105 Cont
但这不起作用。它似乎将 1:2 和 3:4 组合成一个等效范围 (1:4) 并仅将第一个条件分配给该范围,这表明我还需要再次指定该列。当我再次尝试指定列时:
Measurements[c(1:2, 3:4), c("Condition", "Condition")] <- list("Cont", "Exp")
X Data Condition Condition.1
1 90 Cont Exp
2 85 Cont Exp
3 100 Cont Exp
4 105 Cont Exp
出于某种原因,这创建了第二个新列 (??),而且它似乎再次将 1:2 和 3:4 合并为 1:4。所以我想我需要索引 two row ranges 以保持它们 separate 并且只指定一次列,但我被卡住了关于如何做到这一点。我认为解决方案很简单,但我似乎找不到我正在尝试做的事情的例子。也许为了让它们分开,我必须单独分配它们,但我希望有办法。
有人可以帮忙吗?非常感谢 R 新手!
如果您已经有了属于每个条件的观察列表,您可以使用 dplyr::case_when
进行条件变异。根据您存储此信息的方式,您可以使用如下内容:
library(dplyr)
Measurements <- data.frame(X = 1:4,
Data = c(90, 85, 100, 105))
# set which observations belong to each condition
Cont <- 1:2
Exp <- 3:4
Measurements %>%
mutate(Condition = case_when(
X %in% Cont ~ "Cont",
X %in% Exp ~ "Exp"
))
# X Data Condition
# 1 90 Cont
# 2 85 Cont
# 3 100 Exp
# 4 105 Exp
请注意,这不要求观察结果在连续的行中。
了解数据模式和数据 ID 对较大的数据集很有效。
Measurements <- data.frame(X = 1:4, Data = c(90, 85, 100, 105))
dat <- c("Cont","Exp")
pattern <- c(1,1,2,2)
或者从数据中绘制图案,例如条件来自 Measurements$Data
pattern <- sapply( Measurements$Data >=100, function(x){ if(x){2}else{1} } )
# [1] 1 1 2 2
然后你可以简单地添加数据:
Measurements$Condition <- dat[pattern]
# X Data Condition
#1 1 90 Cont
#2 2 85 Cont
#3 3 100 Exp
#4 4 105 Exp
我通常看到这是通过合并操作完成的。诀窍是让您的条件数据变得漂亮。
composeConditions <- function(...) {
conditions <- list(...)
data.frame(
X = unname(unlist(conditions)),
condition = unlist(unname(lapply(
names(conditions),
function(x) rep(x, times = length(conditions[x][[1]]))
)))
)
}
conditions <- composeConditions(Cont = 1:2, Exp = 3:4)
> conditions
X condition
1 1 Cont
2 2 Cont
3 3 Exp
4 4 Exp
merge(Measurements, conditions, by = "X")
X Data condition
1 1 90 Cont
2 2 85 Cont
3 3 100 Exp
4 4 105 Exp