Как зациклить столбцы и установить поднабор данных в соответствии с одним и тем же значением - PullRequest
1 голос
/ 09 июля 2019

Я пытаюсь перебрать столбцы и данные подмножества с одним и тем же значением.

См. Ниже.

White <- rep(0:1, 50)
Latino <- rep(0:1, 50)
Black <- rep(0:1, 50)
Asian <- rep(0:1, 50)
DV <- seq(1: length(rep(0:1, 50)))
x <- data.frame(cbind(White, Latino, Black, Asian, DV))


race <- c("White", "Latino", "Black", "Asian")

for(j in race){
  for (i in race){

    df_1 <- subset(x, i == 1)
    df_2 <- subset(x, j == 1)
    print(paste(i, j, sep = " "))
    print(t.test(df_1$DV, df_2$DV) )


  }
}

К сожалению, r не любит, когда i или j стоят одни. Если кто-нибудь знает лучший способ циклического перебора столбцов для подмножества одного и того же значения, это будет высоко ценится. Спасибо

Ответы [ 3 ]

2 голосов
/ 09 июля 2019

В R мы также можем сделать это с outer

f1 <- function(u, v) list(t.test(x$DV[x[[u]] ==1], x$DV[x[[v]] == 1]))
out <- outer(race, race, FUN = Vectorize(f1))
out[1,1]
#[[1]]

#   Welch Two Sample t-test

#data:  x$DV[x[[u]] == 1] and x$DV[x[[v]] == 1]
#t = 0, df = 98, p-value = 1
#alternative hypothesis: true difference in means is not equal to 0
#95 percent confidence interval:
# -11.57133  11.57133
#sample estimates:
#mean of x mean of y 
#       51        51 

Это может быть сделано в list вывод

lst1 <-  setNames(lapply(out, I), outer(race, race, FUN = paste)
2 голосов
/ 09 июля 2019

Обратите внимание, что i и j в вашем коде - это строка, но на самом деле вы хотели извлечь этот столбец, например

for(j in race){
  for (i in race){

    df_1 <- subset(x, x[,i] == 1)
    df_2 <- subset(x, x[,j] == 1)
    print(paste(i, j, sep = " "))
    print(t.test(df_1$DV, df_2$DV) )


  }
}

Что касается лучшего способа зацикливания, кажется, что фиктивные переменные White, Latino, Black и Asian являются взаимоисключающими, поэтому, возможно, мы могли бы преобразовать данные в

      race  DV
   ------------
1    Black   1
2    White   2
3   Latino   3
4    Black   4
5    Asian   5

и вызовите t.test с формулой, например

# generate synthetic data
rnd.race <- sample(1:4, 50, replace=T)
x <- data.frame(
  White = as.integer(rnd.race == 1),
  Latino = as.integer(rnd.race == 2),
  Black = as.integer(rnd.race == 3),
  Asian = as.integer(rnd.race == 4),
  DV = seq(1: length(rep(0:1, 50)))
)

race <- c("White", "Latino", "Black", "Asian")

# rearrange data, gather columns of dummy variables
x.cleaned = data.frame(
  race = race[apply(x[,1:4], 1, which.max)],
  DV = x$DV
)

t.test( DV ~ race, data=x.cleaned, race %in% c("White", "Black"))

# 
#     Welch Two Sample t-test
# 
# data:  DV by race
# t = -0.91517, df = 42.923, p-value = 0.3652
# alternative hypothesis: true difference in means is not equal to 0
# 95 percent confidence interval:
#  -25.241536   9.483961
# sample estimates:
# mean in group Black mean in group White 
#            47.66667            55.54545 
# 

Преимуществом использования t.test с формулой является ее удобочитаемость. Например, в отчете t.test вместо mean in group x и mean in group y будет указано mean in group Black, mean in group White, а в самой формуле указывается переменная, по которой мы тестируем ковариант по отношению к.

Чтобы итеративно запустить t-критерий для всех пар, мы могли бы

run.test = function(race.pair) {
    list(t.test(DV ~ race, data=x.cleaned, race %in% race.pair) )
}

combn(race, 2, FUN = run.test)

# [[1]]
# 
#     Welch Two Sample t-test
# 
# data:  DV by race
# t = -0.30892, df = 41.997, p-value = 0.7589
# alternative hypothesis: true difference in means is not equal to 0
# 95 percent confidence interval:
#  -21.22870  15.59233
# sample estimates:
# mean in group Latino  mean in group White 
#             52.72727             55.54545 
# 
# 
# [[2]]
# 
#     Welch Two Sample t-test
# 
# data:  DV by race
# t = -0.91517, df = 42.923, p-value = 0.3652
# alternative hypothesis: true difference in means is not equal to 0
# 95 percent confidence interval:
#  -25.241536   9.483961
# sample estimates:
# mean in group Black mean in group White 
#            47.66667            55.54545 
# 
# ...

где combn(x, m, FUN = NULL, simplify = TRUE, ...) - встроенная функция для генерации всех комбинаций элементов x, взятых m за один раз. Более подробный случай с использованием outer см. В ответе @ askrun .


Наконец, ИМХО, возможно, ANOVA более широко признан, чем критерий Стьюдента, при сравнении средних значений между тремя и более группами (может также указывать, почему «неудобно» использовать итеративный критерий Стьюдента для пар групп).

С x.cleaned мы можем легко использовать ANOVA в R, например:

aov.out = aov(DV ~ race, data=x.cleaned)
summary(aov.out)

Обратите внимание, что после одностороннего ANOVA (проверить, отличаются ли некоторые из групповых значений), мы можем также запустить Post Hoc тесты (например, TukeyHSD(aov.out)), чтобы выяснить, есть ли у определенных пар групп разные значения. Несколько проверок предположений также de rigueur в официальном отчете. Здесь - примечания к лекции, связанные с этим. И этот является связанным вопросом о перекрестной проверке (где можно получить ответы на дополнительные вопросы о том, какой тест выбрать).

1 голос
/ 09 июля 2019

Возможно, вам понадобится добавить get

for(j in race){
     for (i in race){

         df_1 <- subset(x, get(i) == 1)
         df_2 <- subset(x, get(j) == 1)
         print(paste(i, j, sep = " "))
         print(t.test(df_1$DV, df_2$DV) )


     }
 }
...