这是我的第一个问题。我正在尽力保持其可复制性。 我找不到解决这个问题的任何问题。
样本数据
library(dplyr)
Data <- data.frame(
a = sample(1:10),
b = sample(c("T", "F"), 10, replace = TRUE),
c = sample(1:10),
x_a = sample(c("T", "F"), 10, replace = TRUE),
x_b = sample(c("T", "F"), 10, replace = TRUE),
y_a = sample(1:10),
y_b = sample(1:10)
)
数据打印
a b c x_a x_b y_a y_b
1 3 T 3 F T 10 8
2 5 F 7 T F 8 9
3 2 T 9 F T 6 4
4 8 F 5 T F 4 7
5 6 F 6 T F 5 1
6 9 F 2 T F 1 10
7 4 F 8 T F 7 5
8 7 F 1 T T 2 2
9 10 F 10 T F 3 3
10 1 F 4 F T 9 6
这就是我想要做的。我想根据以下逻辑创建一个新列。
Data %>% mutate(new = ifelse(starts_with("x") & . == T,rowMeans(starts_with("y")),a))
用词表示:以其名称中的模式cols(starts_with(“ x”))。 如果每个观测值中的一个(最小值)值为True,则从以另一种模式(starts_with(“ y”))命名的cols中获取行平均值。 否则(如果每行中只有False值),请从col a中获取该值。
尝试了多种方法,但成功率为零。我整个上午都在解决问题上... 有任何想法吗?预先谢谢你
答案 0 :(得分:0)
我认为将种子设置为1更好,以便可以复制数据。
set.seed(1)
Data <- data.frame(
a = sample(1:10),
b = sample(c("T", "F"), 10, replace = TRUE),
c = sample(1:10),
x_a = sample(c("T", "F"), 10, replace = TRUE),
x_b = sample(c("T", "F"), 10, replace = TRUE),
y_a = sample(1:10),
y_b = sample(1:10)
)
数据如下:
> Data
a b c x_a x_b y_a y_b
1 3 T 10 T F 5 10
2 4 T 2 F F 8 3
3 5 F 6 T F 4 4
4 7 T 1 T F 2 9
5 2 F 9 F F 1 8
6 8 T 8 F F 6 2
7 9 F 7 F T 7 5
8 6 F 5 T T 9 7
9 10 T 3 F F 3 1
10 1 F 4 T F 10 6
我决定使用type.convert命令将“ T”或“ F”转换为布尔值TRUE或FALSE。
Data<-type.convert(Data)
您现在可以使用Grep选择带有“ x”的列。应用rowSums。您只希望其中一列为TRUE。因此,只要总和大于零,就可以取以y开头的列的平均值:
Data$new<-ifelse(rowSums(Data[,grep("x",colnames(Data))])>0,rowMeans(Data[,grep("y",colnames(Data))]),Data$a)
> Data
a b c x_a x_b y_a y_b new
1 3 TRUE 10 TRUE FALSE 5 10 7.5
2 4 TRUE 2 FALSE FALSE 8 3 4.0
3 5 FALSE 6 TRUE FALSE 4 4 4.0
4 7 TRUE 1 TRUE FALSE 2 9 5.5
5 2 FALSE 9 FALSE FALSE 1 8 2.0
6 8 TRUE 8 FALSE FALSE 6 2 8.0
7 9 FALSE 7 FALSE TRUE 7 5 6.0
8 6 FALSE 5 TRUE TRUE 9 7 8.0
9 10 TRUE 3 FALSE FALSE 3 1 10.0
10 1 FALSE 4 TRUE FALSE 10 6 8.0
答案 1 :(得分:0)
rowMeans不能直接与“ Starts_with”一起使用,因为它需要一定范围的列来计算均值。以下将适用于您的上述情况:
Data <- Data %>% mutate(new = ifelse(x_a == 'T' | x_b == 'T',rowMeans(dplyr::select(.,starts_with("y"))),a))
您可以直接使用'select'代替'dplyr :: select',因为我的情况下存在某些版本问题!