Линейная регрессия на 415 файлах, вывод только имени файла, коэффициент регрессии, значимость - PullRequest
0 голосов
/ 25 января 2020

Я новичок в R, я изучаю основы для анализа некоторых биологических данных. У меня есть 415 файлов .csv, каждый из которых является грибковым видом. Каждый файл имеет 5 столбцов - (ГОД, FFD, LFD, MEAN, RANGE)

    YEAR    FFD LFD RAN MEAN
1   1950    NA  NA  NA  NA
2   1951    NA  NA  NA  NA
3   1952    NA  NA  NA  NA
4   1953    NA  NA  NA  NA
5   1954    NA  NA  NA  NA
6   1955    NA  NA  NA  NA
7   1956    NA  NA  NA  NA
8   1957    NA  NA  NA  NA
9   1958    NA  NA  NA  NA
10  1959    140 141 1   140
11  1960    NA  NA  NA  NA
12  1961    NA  NA  NA  NA
13  1962    NA  NA  NA  NA
14  1963    NA  NA  NA  NA
15  1964    NA  NA  NA  NA
16  1965    155 156 1   155
17  1966    NA  NA  NA  NA
18  1967    NA  NA  NA  NA
19  1968    152 153 1   152
20  1969    NA  NA  NA  NA
21  1970    NA  NA  NA  NA
22  1971    161 162 1   161
23  1972    NA  NA  NA  NA
24  1973    143 144 1   143
25  1974    NA  NA  NA  NA
26  1975    NA  NA  NA  NA
27  1976    NA  NA  NA  NA
28  1977    NA  NA  NA  NA
29  1978    NA  NA  NA  NA
30  1979    NA  NA  NA  NA
31  1980    NA  NA  NA  NA
32  1981    NA  NA  NA  NA
33  1982    155 156 1   155
34  1983    NA  NA  NA  NA
35  1984    NA  NA  NA  NA
36  1985    157 158 1   157
37  1986    170 310 140 240
38  1987    173 274 101 232
39  1988    192 236 44  214
40  1989    234 320 86  277
41  1990    172 287 115 213
42  1991    148 287 139 205
43  1992    140 278 138 206
44  1993    152 273 121 216
45  1994    142 319 177 228
46  1995    261 318 57  287
47  1996    247 315 68  285
48  1997    164 270 106 230
49  1998    186 187 1   186
50  1999    235 236 1   235
51  2000    NA  NA  NA  NA
52  2001    309 310 1   309
53  2002    203 308 105 256
54  2003    140 238 98  189
55  2004    204 313 109 267
56  2005    253 313 60  287
57  2006    247 300 53  279
58  2007    185 295 110 225
59  2008    259 260 1   259
60  2009    296 315 19  309
61  2010    230 303 73  275
62  2011    247 248 1   247
63  2012    206 207 1   206
64  2013    NA  NA  NA  NA
65  2014    250 317 67  271

Сначала я хотел бы увидеть коэффициент регрессии (наклон линии) для каждого файла и значение (p -значение) для всех файлов.

Я могу сделать это индивидуально с помощью:

fruit<-read.csv(file.choose(),header=TRUE)
yr<-fruit[,1]
ffd<-fruit[,2]
res<-lm(ffd~yr)
summary(res)

когда я делаю это для данных, я получаю:

Call:
lm(formula = ffd ~ yr)

Residuals:
    Min      1Q  Median      3Q     Max 
-77.358 -20.858  -5.714  22.494  96.015 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) -4162.0710   950.1439  -4.380 0.000119 ***
yr              2.1864     0.4765   4.588 6.55e-05 ***
---
Signif. codes:  
0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 38.75 on 32 degrees of freedom
  (31 observations deleted due to missingness)
Multiple R-squared:  0.3968,    Adjusted R-squared:  0.378 
F-statistic: 21.05 on 1 and 32 DF,  p-value: 6.549e-05

Единственная информация, которая мне нужна на данный момент, - это коэффициент регрессии (2.1864) и значение p (6.549e-05)

Идеальный результат был бы, если бы я мог заставить R циклически проходить через 415 файлы и дать вывод в виде таблицы с 3 столбцами: имя файла, коэффициент регрессии и значимость. Было бы 415 строк, по одной для каждого файла.

Затем я хотел бы сделать YEAR ~ LFD, YEAR ~ RANGE и YEAR ~ MEAN. Я надеюсь, что смогу легко отредактировать код для YEAR ~ FFD и запустить его для других 3 регрессий.

Ответы [ 4 ]

4 голосов
/ 25 января 2020

Следующий код, вероятно, будет работать.
Я проверил его с вашими данными в двух файлах. Вот функции, которые выполняют всю работу:

regrFun <- function(DF){
  fit <- lm(DF[[1]] ~ DF[[2]])
  coef(summary(fit))[2, c(1, 4)]
}
regrList <- function(iv, L){
  res <- lapply(seq_along(L), function(i){
    dftmp <- L[[i]]
    cfs <- regrFun(dftmp[c(1, iv)])
    data.frame(file = names(L)[i], Estimate = cfs[1], p.value = cfs[2])
  })
  res <- do.call(rbind, res)
  row.names(res) <- NULL
  res
}

Теперь прочитайте данные в файлах данных. В следующей строке кода замените общую часть имени файла на "pattern" в очевидном месте.

filenames <- list.files(pattern = "pattern")
df_list <- lapply(filenames, read.csv)
names(df_list) <- filenames

и вычислите нужные значения.

results_list <- lapply(2:ncol(df_list[[1]]), regrList, df_list)
names(results_list) <- names(df_list[[1]][-1])
3 голосов
/ 25 января 2020

Сначала я имитирую, как 5 CSV-файлов, с колонками, которые выглядят как ваши:

for(i in 1:5){
  tab=data.frame(
      YEAR=1950:2014,
      FFD= rpois(65,100),
      LFD= rnorm(65,100,10),
      RAN= rnbinom(65,mu=100,size=1),
      MEAN = runif(65,min=50,max=150)
  )
  write.csv(tab,paste0("data",i,".csv"))
}

Теперь нам нужен вектор всех файлов в вашем каталоге, это будет отличаться для вашего, но попробуйте чтобы создать это каким-то образом, используя аргумент шаблона:

csvfiles = dir(pattern="data[0-9]*.csv$")

Итак, мы используем три библиотеки из tidyverse, и я предполагаю, что каждый CSV-файл не такой большой, поэтому код ниже читает все файлы, группируя их по источник и выполняет регрессию, обратите внимание, что вы можете использовать вызов столбцов из фрейма данных, без необходимости переименовывать их:

library(dplyr)
library(purrr)
library(broom)

csvfiles %>% 
map_df(function(i){df = read.csv(i);df$data = i;df}) %>%  
group_by(data) %>% 
do(tidy(lm(FFD ~ YEAR,data=.))) %>% 
filter(term!="(Intercept)")

# A tibble: 5 x 6
# Groups:   data [5]
  data      term  estimate std.error statistic p.value
  <chr>     <chr>    <dbl>     <dbl>     <dbl>   <dbl>
1 data1.csv YEAR   -0.0228    0.0731    -0.311 0.756  
2 data2.csv YEAR   -0.139     0.0573    -2.42  0.0182 
3 data3.csv YEAR   -0.175     0.0650    -2.70  0.00901
4 data4.csv YEAR   -0.0478    0.0628    -0.762 0.449  
5 data5.csv YEAR    0.0204    0.0648     0.315 0.754  

Вы можете просто изменить формулу внутри lm(FFD ~ YEAR,data=.), чтобы получить другие регрессии

1 голос
/ 25 января 2020

data.table версия, с использованием макета csv-файлов StupidWolf и именами полей с запрошенными полями:

library(data.table)

input.dir = "/home/user/Desktop/My Folder/" # adjust to your needs
csvfiles <- list.files(path=input.dir, full.names=TRUE, pattern=".*data(.*)\\.csv") # adjust pattern

Выше я использовал более конкретный c шаблон регулярного выражения, но вы можете просто выбрать шаблон = «* .csv», если вы хотите обработать все CSV-файлы в этой папке.

# order the files
csvfiles <- csvfiles[order(as.numeric(gsub(".*data(.*)\\.csv", "\\1", csvfiles)))]

# function to read file and return requested columns
regrFun <- function(x){
    DT <- fread(x)
    fit <- lm(FFD ~ YEAR, data=DT)
    return(as.list(c(filename=basename(x), coef(summary(fit))[2, c(1, 4)])))
}

# apply function and rename columns
DT <- rbindlist(lapply(csvfiles, regrFun))
setnames(DT, c("filename", "regression coefficient", "significance"))

DT

Результат:

        filename regression coefficient       significance
  1:   data1.csv     -0.113286713286712 0.0874762832713643
  2:   data2.csv     -0.044449300699302  0.457096760642717
  3:   data3.csv     0.0464597902097902  0.499618510612891
  4:   data4.csv     -0.032473776223776  0.638494798460044
  5:   data5.csv     0.0562062937062939  0.452955919860998
 ---                                                      
411: data411.csv     0.0381555944055959  0.544185411150829
412: data412.csv    -0.0672202797202807  0.314346452751388
413: data413.csv      0.116564685314687 0.0694785724198052
414: data414.csv    -0.0908216783216786  0.110811677724832
415: data415.csv    -0.0282779720279721  0.638766712090455
0 голосов
/ 25 января 2020

Вы можете написать сценарий R, который выполняется для одного файла, а затем запустить его для каждого файла через терминал.

Этот сценарий представляет собой просто файл .R с кодом внутри. Чтобы запустить его для каждого файла, вы должны выполнить на своем терминале что-то в строках (используя bash)

for file in $(ls yourDataDirectory); do
    Rscript yourScriptFile.R $file >> finalOutput
done

Это запустит скрипт в yourScriptFile.R для каждого файла в вашем DataDircetory и сохранит вывод on finalOutput.

Сам код сценария будет очень похож на тот, который вы уже написали, но вместо file.choose() вы будете использовать аргумент, передаваемый командной строкой, как описано здесь и вам придется печатать только интересующую вас информацию вместо вывода summary. finalOutput может быть даже файлом csv, если вы правильно отформатируете вывод скрипта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...